<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Feranmi Okafor</title>
    <description>The latest articles on DEV Community by Feranmi Okafor (@feranmiokafor).</description>
    <link>https://dev.to/feranmiokafor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1252677%2F004b3638-b63a-446d-9c58-80649261fb6e.png</url>
      <title>DEV Community: Feranmi Okafor</title>
      <link>https://dev.to/feranmiokafor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/feranmiokafor"/>
    <language>en</language>
    <item>
      <title>Introducing our new monthly release schedule</title>
      <dc:creator>Feranmi Okafor</dc:creator>
      <pubDate>Fri, 12 Jan 2024 15:20:25 +0000</pubDate>
      <link>https://dev.to/surrealdb/introducing-our-new-monthly-release-schedule-1mbe</link>
      <guid>https://dev.to/surrealdb/introducing-our-new-monthly-release-schedule-1mbe</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fapobieycchw8fx74j9n6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fapobieycchw8fx74j9n6.png" alt="SurrealDB Release Train"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
Over the course of the last 18 months, SurrealDB product releases have been feature-driven, rolling out updates as and when they were ready. This approach, while flexible, often led to unpredictable release dates which could cause challenges for users of the database, and engineers who develop against our embedded Rust SDK.&lt;br&gt;
​&lt;br&gt;
In our pursuit of improvement and efficiency, we are excited to announce a significant shift in our product release schedule. Taking inspiration from the Rust programming language’s release train model, we are transitioning to a more structured, monthly release cycle. This process will ensure that we release often, with predictable updates and product patches, allowing developers and organisations to build on top of SurrealDB, with predictable timelines for software improvements and fixes.&lt;br&gt;
​&lt;br&gt;
With this new release cycle, on the second Tuesday of each month, a new beta version of SurrealDB will be released, allowing users to test and update their software locally and in continuous integration environments, before the stable release of that version. On the second Tuesday of the following month, the beta release will be promoted to a stable release version, at which time a new beta version will be released.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Release channels
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
With this new approach to releases there are now three &lt;em&gt;release channels&lt;/em&gt; for the SurrealDB database server, and SurrealDB Rust client.&lt;br&gt;
​&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nightly (along with a &lt;a href="https://crates.io/crates/surrealdb-nightly" rel="noopener noreferrer"&gt;&lt;code&gt;surrealdb-nightly&lt;/code&gt;&lt;/a&gt; Rust crate)&lt;/li&gt;
&lt;li&gt;Beta (along with a &lt;a href="https://crates.io/crates/surrealdb-beta" rel="noopener noreferrer"&gt;&lt;code&gt;surrealdb-beta&lt;/code&gt;&lt;/a&gt; Rust crate)&lt;/li&gt;
&lt;li&gt;Stable (available with the &lt;a href="https://crates.io/crates/surrealdb" rel="noopener noreferrer"&gt;&lt;code&gt;surrealdb&lt;/code&gt;&lt;/a&gt; Rust crate)
​
Most developers and organisations will primarily use the stable release channel, but those who want to try out future or new experimental features may use the beta or nightly channels.
​
Every night a new nightly version of the crate, and of the database server are released, both as a downloadable binary, and as an embeddable library. On the second Tuesday of each month, a new beta release is made consisting of the new features and improvements available in the nightly releases. Over the course of the next month, a number of further beta releases will be made as features are stabilised. On the second Tuesday of the following month, the beta release becomes stable, ensuring users can upgrade to the latest stable version.
​
Here’s an example of how the development and release process works. Each night, a new nightly version of the SurrealDB server and library are produced. Every day is a release day, and these releases are created by our release infrastructure automatically. So as time passes, our releases look like this, once a night:
​
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nightly: * - - * - - *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;​&lt;br&gt;
On the second Tuesday of every month, we build and deploy a new release. The beta branch of the SurrealDB repository branches off from the main branch from which the nightly releases are made. Now, there are two releases:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nightly: * - - * - - *
                     |
beta:                *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
Some SurrealDB users will actively test against the beta release in continuous integration environments to help discover any possible regressions. In addition, the beta release can be used to develop applications locally, to ensure that future functionality can be used within projects. In the meantime, there’s still a nightly release every night:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nightly: * - - * - - * - - * - - *
                     |
beta:                *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
Let’s say a regression is found. Good thing we had some time to test the beta release before the regression snuck into a stable release! The fix is applied to the main branch, so that the nightly release is fixed, and then the fix is backported to the beta branch, and a new release of beta is produced:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
On the second Tuesday of the following month, after the beta was created, it’s time for a stable release. The stable branch is now produced from the beta branch:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
We now have a new stable release of SurrealDB! Which is great. In addition however, we also need a new beta of the next version of SurrealDB. So after stable branches off of beta, the next version of beta branches off of nightly again:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
In a similar manner to Rust's release train model which occurs every 6 weeks, the SurrealDB release train will guarantee a timely and reliable release progression. This is called the 'train model' because every month, a new release 'leaves the station', but still has to take a journey through the beta channel before it arrives as a stable release.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Change?
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
The unpredictability of our current process sometimes led to prolonged periods without updates, followed by a flood of changes. This irregularity can be disorienting and inconvenient for developers and organisations building on top of SurrealDB. Monthly releases strike a balance between the rapid iteration of continuous delivery and the stability of longer release cycles. They allow us to incorporate user feedback more swiftly and maintain a consistent development pace. Regular releases will provide our users with a predictable schedule, allowing them to plan for and adapt to new changes more effectively. This model enables us to iterate quickly and incorporate user feedback into subsequent releases, significantly improving the overall quality of the SurrealDB platform.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
Our goal is to make our product more reliable and user-friendly. We expect this change to significantly enhance our ability to meet and exceed user expectations. We believe this new monthly release schedule will bring a new level of efficiency and predictability to our product development. We're excited about this change and confident it will bring about positive outcomes for both our team and our users.&lt;br&gt;
​&lt;br&gt;
We would love to hear your thoughts on this new approach. Please feel free to provide feedback, subscribe to our updates, or join our community forum to engage in further discussion.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>database</category>
      <category>devops</category>
      <category>community</category>
    </item>
    <item>
      <title>Introducing Nightly and Beta Rust Crates</title>
      <dc:creator>Feranmi Okafor</dc:creator>
      <pubDate>Wed, 10 Jan 2024 11:43:56 +0000</pubDate>
      <link>https://dev.to/surrealdb/introducing-nightly-and-beta-rust-crates-5bd0</link>
      <guid>https://dev.to/surrealdb/introducing-nightly-and-beta-rust-crates-5bd0</guid>
      <description>&lt;p&gt;We are pleased to announce two additional Rust crates, &lt;code&gt;surrealdb-nightly&lt;/code&gt; and &lt;code&gt;surrealdb-beta&lt;/code&gt;. These crates are designed to complement the &lt;code&gt;surrealdb&lt;/code&gt; crate. Starting with &lt;code&gt;v1.1.0&lt;/code&gt; we plan to publish a stable release on the second Tuesday of every month. These stable releases are only published to the stable &lt;code&gt;surrealdb&lt;/code&gt; crate. &lt;/p&gt;

&lt;p&gt;If you use SurrealDB in production, this is the ideal crate for you. You can add it to your project using &lt;code&gt;cargo add&lt;/code&gt; or by simply adding a line like this one to your dependencies section:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;surrealdb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;/p&gt;

&lt;h2&gt;
  
  
  Nightly Crate
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
If you prefer living on the bleeding edge, this crate is perfect for you. It follows our development branch very closely. It’s automatically published every night but only when there are new changes to the development branch. It makes it easy to test new features as an embedded library or as a client when running a nightly binary on the server.&lt;br&gt;
​&lt;br&gt;
When using nightly or beta crates, we recommend adding a line similar to this one to your dependencies section in Cargo.toml:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;surrealdb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;package&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"surrealdb-nightly"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
This makes it easy to switch between the three crates by simply changing the package name. You could start your development using &lt;code&gt;surrealdb-nightly&lt;/code&gt; if the nightly version has a feature you want that hasn’t stabilised yet, later switch to &lt;code&gt;surrealdb-beta&lt;/code&gt; once it reaches beta and finally switch to &lt;code&gt;surrealdb&lt;/code&gt; once it’s stable. All this by simply changing the package name. This way you won’t have to update your feature flag names if you have features that activate SurrealDB features. For example &lt;code&gt;memory = ["surrealdb/kv-mem"]&lt;/code&gt;.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  Beta Crate
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
Every month we will freeze features on the development branch by creating a new branch which will only receive bug fixes from that point onwards. This gives us a month to polish our releases before they hit the stable crate. Updates in that branch are pushed to the &lt;code&gt;surrealdb-beta&lt;/code&gt; crate. New features in this crate are not guaranteed to reach the stable crate. Such features may be reverted to give them more time to develop if we think they are not ready to stabilise yet.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
The nightly and beta crates are great for testing new features and bug fixes. However, these are, by definition, pre-releases. Use them responsibly 😄.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>database</category>
      <category>rust</category>
      <category>data</category>
    </item>
    <item>
      <title>Live Queries in Rust</title>
      <dc:creator>Feranmi Okafor</dc:creator>
      <pubDate>Wed, 10 Jan 2024 11:30:14 +0000</pubDate>
      <link>https://dev.to/surrealdb/live-queries-in-rust-3dh4</link>
      <guid>https://dev.to/surrealdb/live-queries-in-rust-3dh4</guid>
      <description>&lt;p&gt;SurrealDB comes with a &lt;code&gt;LIVE SELECT&lt;/code&gt; &lt;a href="https://docs.surrealdb.com/docs/surrealql/statements/live-select/"&gt;statement&lt;/a&gt; that allows you to listen for creations, updates and deletions to specific records you are interested in or entire tables. While you could already take advantage of this powerful feature with our JavaScript SDK or WebSockets, the Rust SDK &lt;a href="https://docs.rs/surrealdb-beta/1.1.0/surrealdb/method/struct.Select.html#method.live"&gt;added an API for it in v1.1.0&lt;/a&gt;.&lt;br&gt;
​&lt;br&gt;
The Rust API for live queries builds on top of the already existing &lt;code&gt;select&lt;/code&gt; method by simply adding a &lt;code&gt;live&lt;/code&gt; method which converts the select query into a live select one. It works seamlessly with our current API, so you can use it with single records, a range of records, or entire tables. Unlike the normal select method which returns either a single result or a vector of results, it returns a stream of notifications. This works for the WebSocket engine and the local ones (the key value stores you can embed in your app). The only engine not yet supported is the HTTP one.&lt;br&gt;
​&lt;br&gt;
In this article, we show some examples of running live queries via the Rust SDK. We will skip imports for brevity but your IDE and/or the Rust compiler should give you the correct suggestions. Please refer to &lt;a href="https://github.com/surrealdb/surrealdb/blob/8e9bd3a2d6289118a79822a48e2c45541020dfdf/lib/examples/live/main.rs"&gt;this example&lt;/a&gt; in our repo for a full, working example.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Connect to a WebSocket endpoint&lt;/span&gt;
&lt;span class="c1"&gt;// We are using the WebSocket engine for this example but you can also&lt;/span&gt;
&lt;span class="c1"&gt;// use a local engine embeded in your app.&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Surreal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;new&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Ws&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost:8000"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// Signin as a namespace, database, or root user&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.signin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// Select a specific namespace / database&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.use_ns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"namespace"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.use_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
Once you have signed into your server and selected the namespace and database to use, you are ready to start sending queries to your database.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Listening for Changes on a Table
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Listen to all updates on the person table&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
This query listens to all changes made on the &lt;code&gt;person&lt;/code&gt; table and returns a stream of notification results. Since the Rust SDK automatically deserialises responses on your behalf, you will either need to give the compiler a way to infer the response type of the notifications, or manually tell it what the response type should be. There are multiple ways to do this. The best one for you will depend on how you structure the rest of your code. In this article, we are going to process responses from a function. This allows the compiler to infer the type from the function parameter.&lt;br&gt;
​&lt;br&gt;
Let’s define a &lt;code&gt;handle&lt;/code&gt; function that simply prints out the &lt;a href="https://docs.rs/surrealdb-beta/1.1.2/surrealdb/struct.Notification.html"&gt;notification&lt;/a&gt; results:&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Handle the result of the live query notification&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Notification&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{notification:?}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{error}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
&lt;code&gt;Person&lt;/code&gt;, in this case, is what you expect the records coming from the database to deserialise into. This means that it must implement &lt;code&gt;serde::Deserialize&lt;/code&gt;. &lt;code&gt;notification.action&lt;/code&gt; will tell you whether the action that triggered this notification was a creation, update or deletion. &lt;code&gt;[notification.data](http://notification.data)&lt;/code&gt; will contain your deserialised object, &lt;code&gt;Person&lt;/code&gt; in this particular case.&lt;br&gt;
​&lt;br&gt;
With this out of the way, we can now listen to changes being made on the table and process them in real time.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The returned stream implements `futures::Stream` so we can&lt;/span&gt;
&lt;span class="c1"&gt;// use it with `futures::StreamExt`&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
If you do not care about strong types for your particular use case or you simply want to try out the feature, you can use &lt;code&gt;surrealdb::opt::Resource&lt;/code&gt; as your select parameter. This makes the compiler infer that the response type will be &lt;code&gt;surrealdb::sql::Value&lt;/code&gt; so you won’t need to define it in that case.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Listen to all updates on the person table&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// The returned stream implements `futures::Stream` so we can&lt;/span&gt;
&lt;span class="c1"&gt;// use it with `futures::StreamExt`&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{notification:?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
That’s all you need when using &lt;code&gt;Resource&lt;/code&gt;. It doesn’t return a result because &lt;code&gt;Value&lt;/code&gt;s are not deserialised first and if a notification itself can’t be deserialised from a remote server, it can’t be routed anyway. &lt;code&gt;surrealdb::sql::Value&lt;/code&gt; is the internal type SurrealDB uses so it’s returned as is. This is not unique to live queries or new to this release. Resources can be used with any CRUD method.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Listening for Changes on a Range of Records
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
Listening on a range of records is simply a matter of using the &lt;code&gt;range&lt;/code&gt; method on a select query before calling &lt;code&gt;live&lt;/code&gt; on it.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;// This is a range on the `id` of the person&lt;/span&gt;
    &lt;span class="nf"&gt;.range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jane"&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="s"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{notification:?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
Again, we are using &lt;code&gt;Resource&lt;/code&gt; as a parameter here for brevity but the first approach works too. the only difference with this code is the &lt;code&gt;range&lt;/code&gt; method. This supports the full range syntax that Rust supports; &lt;code&gt;start..end&lt;/code&gt;, &lt;code&gt;start..&lt;/code&gt;, &lt;code&gt;..&lt;/code&gt;, &lt;code&gt;start..=end&lt;/code&gt;, &lt;code&gt;..end&lt;/code&gt; and &lt;code&gt;..=end&lt;/code&gt;. You can also specify the bounds manually using the &lt;a href="https://doc.rust-lang.org/std/ops/enum.Bound.html"&gt;Bound&lt;/a&gt; enum directly, &lt;code&gt;(start, end)&lt;/code&gt;, for extra flexibility.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Listening to Changes on a Single Record
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
As you may have guessed already, listening to changes on a particular &lt;code&gt;Person&lt;/code&gt; record is not much different from what we have done so far. In this case, we simply need to listen on a record ID instead of a table.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Listen only to changes happening to John's data&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{notification:?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
If you need to listen to changes happening to your data in real-time, live queries are a powerful feature that enables you to do this. They integrate seamlessly with the Rust SDK allowing you to take advantage of the other SurrealDB features like authentication and permissions. The SDK also manages creating and closing the query for you automatically. As you may have noticed, we did not need to manually close the stream after using it. It’s automatically closed when the stream is dropped. Do try out the Live Queries in the Rust SDK &amp;amp; share your experience in our &lt;a href="https://surrealdb.com/community"&gt;community&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>database</category>
      <category>rust</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Release v1.1.0</title>
      <dc:creator>Feranmi Okafor</dc:creator>
      <pubDate>Tue, 09 Jan 2024 17:50:29 +0000</pubDate>
      <link>https://dev.to/surrealdb/release-v110-5376</link>
      <guid>https://dev.to/surrealdb/release-v110-5376</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6okv5qmj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h96tevnolj8jo9707x3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6okv5qmj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h96tevnolj8jo9707x3c.png" alt="SurrealDB v1.1.0 Release" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Hello developers!&lt;br&gt;
​&lt;br&gt;
After months of hard work, we're excited to roll out v1.1.0 .&lt;br&gt;
​&lt;br&gt;
This release is packed with features and improvements that we believe will make your development experience smoother and more efficient. From additional configuration flags, performance improvements, memory leak fixes, bug fixes, and new features, there's a lot to explore. We've also improved the internal memory allocators and released machine learning model computation powered by SurrealML. This release incorporates a number of contributions and feature suggestions from the community. For full release information, view the &lt;a href="https://dev.to/releases#v1-1-0"&gt;release notes&lt;/a&gt;.&lt;br&gt;
​&lt;br&gt;
Let's dive right into it and see what's new:&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Run machine learning models in SurrealQL
&lt;/h2&gt;

&lt;p&gt;​&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VKNMr28c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vaqh6x9gote9ccfmcccg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VKNMr28c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vaqh6x9gote9ccfmcccg.png" alt="SurrealML functionality" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
​&lt;br&gt;
SurrealML is our first step towards bringing Machine Learning to the Surreal ecosystem. With the introduction of our own file format with metadata and versioning included within the file, machine learning models can be greatly simplified, ensuring reproducibility and consistency in machine learning pipelines.&lt;br&gt;
​&lt;br&gt;
Using the &lt;code&gt;surreal&lt;/code&gt; command line tool, we can import our SurrealML models directly into SurrealDB, effortlessly. SurrealDB automatically reads and understands the model requirements, immediately setting up a custom in-built function which can be used to infer results from the model itself. Inference works with either raw data inputs, for advanced usage, or with the field-name key bindings, packaged into the SurrealML file format itself. Developers no longer have to use external platforms or systems to run model predictions against data residing in their database. Instead the model logic can sit directly within the SurrealQL language, extending the power of custom functions.&lt;br&gt;
​&lt;br&gt;
As with live queries, the real power comes when we combine this functionality with the other powerful features within SurrealQL. Model inference can now be used seamlessly within EVENTs, LIVE QUERIES, and custom functions, both as a traditional database backend, or connected to directly from the browser.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;house_listing&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;squarefoot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_floors_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;house_listing&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;squarefoot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_floors_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;house_listing&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;squarefoot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_floors_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; 
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;ml&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;houses&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;prediction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
            &lt;span class="n"&gt;squarefoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;squarefoot_col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;num_floors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;num_floors_col&lt;/span&gt; 
        &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;price_prediction&lt;/span&gt; 
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;house_listing&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;price_prediction&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;177206&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;21875&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
For more information regarding SurrealML, view the &lt;a href="https://docs.surrealdb.com"&gt;documentation&lt;/a&gt; and read the &lt;a href="https://dev.to/blog/what-is-surrealml-a-getting-started-guide"&gt;blog&lt;/a&gt; post.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  Use live queries in the Rust SDK
&lt;/h2&gt;

&lt;p&gt;​&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XvwEGllX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2hmqgm72gdm043z9r94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XvwEGllX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2hmqgm72gdm043z9r94.png" alt="Live Queries functionality" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
​&lt;br&gt;
This release introduces a new Live Query API to the Rust SDK, for powerful realtime updates in your Rust applications. By simply specifying &lt;code&gt;.live()&lt;/code&gt; at the end of a &lt;code&gt;select()&lt;/code&gt; query, you can receive a stream of changes, as they occur whtin a local or remote database.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Select the namespace/database to use&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.use_ns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"namespace"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.use_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// Listen to all updates on a table&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// Listen to updates on a range of records&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jane"&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="s"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// Listen to updates on a specific record&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="nf"&gt;.select&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"h5wxrf2ewk8xjxosxtyc"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// The returned stream implements `futures::Stream` so we can&lt;/span&gt;
&lt;span class="c1"&gt;// use it with `futures::StreamExt`, for example.&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;// Handle the result of the live query notification&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Notification&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{notification:?}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{error}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved string parsing functionality
&lt;/h2&gt;

&lt;p&gt;​&lt;br&gt;
Previously, any string within SurrealQL was parsed as a Record ID, Datetime, or UUID if they had the same format as one of those types. In this release, string prefixes allow you to decide what value a string holds, forcing it to be parsed as a raw string, or forcing it to be parsed as a specific type.&lt;br&gt;
​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Interpeted as a record ID, because of the structure with the semicolon:&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nv"&gt;"5:20"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Forcefully parsed as just a string&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nv"&gt;"5:20"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;-- This will be a record ID.&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nv"&gt;"person:john"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- This fails, as it's not a valid record ID.&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nv"&gt;"I am not a record ID"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="c1"&gt;-- Example for a date and a UUID.&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="nv"&gt;"2023-11-28T11:41:20.262Z"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="nv"&gt;"8c54161f-d4fe-4a74-9409-ed1e137040c1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​&lt;br&gt;
We're excited to see what users will build with the new functionality and performance improvements introduced in this release. For questions, find us on &lt;a href="https://github.com/surrealdb"&gt;GitHub&lt;/a&gt; and &lt;a href="https://discord.gg/surrealdb"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>devops</category>
      <category>database</category>
    </item>
  </channel>
</rss>
