surrealdb/lib.rs
1//! This library provides a low-level database library implementation, a remote client
2//! and a query language definition, for [SurrealDB](https://surrealdb.com), the ultimate cloud database for
3//! tomorrow's applications. SurrealDB is a scalable, distributed, collaborative, document-graph
4//! database for the realtime web.
5//!
6//! This library can be used to start an embedded in-memory datastore, an embedded datastore
7//! persisted to disk, a browser-based embedded datastore backed by IndexedDB, or for connecting
8//! to a distributed [TiKV](https://tikv.org) key-value store.
9//!
10//! It also enables simple and advanced querying of a remote SurrealDB server from
11//! server-side or client-side code. All connections to SurrealDB are made over WebSockets by default,
12//! and automatically reconnect when the connection is terminated.
13//!
14//! # Examples
15//!
16//! ```no_run
17//! use serde::{Serialize, Deserialize};
18//! use serde_json::json;
19//! use std::borrow::Cow;
20//! use surrealdb::{Result, Surreal};
21//! use surrealdb::sql;
22//! use surrealdb::opt::auth::Root;
23//! use surrealdb::engine::remote::ws::Ws;
24//!
25//! #[derive(Serialize, Deserialize)]
26//! struct Name {
27//! first: Cow<'static, str>,
28//! last: Cow<'static, str>,
29//! }
30//!
31//! #[derive(Serialize, Deserialize)]
32//! struct Person {
33//! title: Cow<'static, str>,
34//! name: Name,
35//! marketing: bool,
36//! }
37//!
38//! #[tokio::main]
39//! async fn main() -> Result<()> {
40//! let db = Surreal::new::<Ws>("localhost:8000").await?;
41//!
42//! // Signin as a namespace, database, or root user
43//! db.signin(Root {
44//! username: "root",
45//! password: "root",
46//! }).await?;
47//!
48//! // Select a specific namespace / database
49//! db.use_ns("namespace").use_db("database").await?;
50//!
51//! // Create a new person with a random ID
52//! let created: Vec<Person> = db.create("person")
53//! .content(Person {
54//! title: "Founder & CEO".into(),
55//! name: Name {
56//! first: "Tobie".into(),
57//! last: "Morgan Hitchcock".into(),
58//! },
59//! marketing: true,
60//! })
61//! .await?;
62//!
63//! // Create a new person with a specific ID
64//! let created: Option<Person> = db.create(("person", "jaime"))
65//! .content(Person {
66//! title: "Founder & COO".into(),
67//! name: Name {
68//! first: "Jaime".into(),
69//! last: "Morgan Hitchcock".into(),
70//! },
71//! marketing: false,
72//! })
73//! .await?;
74//!
75//! // Update a person record with a specific ID
76//! let updated: Option<Person> = db.update(("person", "jaime"))
77//! .merge(json!({"marketing": true}))
78//! .await?;
79//!
80//! // Select all people records
81//! let people: Vec<Person> = db.select("person").await?;
82//!
83//! // Perform a custom advanced query
84//! let sql = r#"
85//! SELECT marketing, count()
86//! FROM type::table($table)
87//! GROUP BY marketing
88//! "#;
89//!
90//! let groups = db.query(sql)
91//! .bind(("table", "person"))
92//! .await?;
93//!
94//! Ok(())
95//! }
96//! ```
97
98#![doc(html_favicon_url = "https://surrealdb.s3.amazonaws.com/favicon.png")]
99#![doc(html_logo_url = "https://surrealdb.s3.amazonaws.com/icon.png")]
100#![cfg_attr(docsrs, feature(doc_cfg))]
101#![cfg_attr(test, deny(warnings))]
102
103#[macro_use]
104extern crate tracing;
105
106#[macro_use]
107mod mac;
108
109mod api;
110mod cf;
111mod ctx;
112mod doc;
113mod exe;
114mod fnc;
115mod vs;
116
117pub mod sql;
118
119// #[doc(inline)]
120pub mod cnf;
121// #[doc(inline)]
122pub mod dbs;
123// #[doc(inline)]
124pub mod env;
125// #[doc(inline)]
126pub mod err;
127// #[doc(inline)]
128pub mod iam;
129// #[doc(inline)]
130pub mod idg;
131// #[doc(inline)]
132pub mod idx;
133// #[doc(inline)]
134pub mod key;
135// #[doc(inline)]
136pub mod kvs;
137// #[doc(inline)]
138pub mod syn;
139
140/*
141#[doc(inline)]
142pub use self::cnf;
143#[doc(inline)]
144pub use self::dbs;
145#[doc(inline)]
146pub use self::env;
147#[doc(inline)]
148pub use self::err;
149#[doc(inline)]
150pub use self::iam;
151#[doc(inline)]
152pub use self::idg;
153#[doc(inline)]
154pub use self::idx;
155#[doc(inline)]
156pub use self::key;
157#[doc(inline)]
158pub use self::kvs;
159#[doc(inline)]
160pub use self::syn;
161*/
162
163#[doc(inline)]
164pub use api::engine;
165#[doc(inline)]
166pub use api::method;
167#[doc(inline)]
168pub use api::opt;
169#[doc(inline)]
170pub use api::Connect;
171#[doc(inline)]
172pub use api::Connection;
173#[doc(inline)]
174pub use api::Response;
175#[doc(inline)]
176pub use api::Result;
177#[doc(inline)]
178pub use api::Surreal;
179
180#[doc(hidden)]
181/// Channels for receiving a SurrealQL database export
182pub mod channel {
183 pub use channel::bounded;
184 pub use channel::unbounded;
185 pub use channel::Receiver;
186 pub use channel::Sender;
187}
188
189/// Different error types for embedded and remote databases
190pub mod error {
191 pub use crate::api::err::Error as Api;
192 pub use crate::err::Error as Db;
193}
194
195/// The action performed on a record
196///
197/// This is used in live query notifications.
198#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
199#[non_exhaustive]
200pub enum Action {
201 Create,
202 Update,
203 Delete,
204}
205
206impl From<dbs::Action> for Action {
207 fn from(action: dbs::Action) -> Self {
208 match action {
209 dbs::Action::Create => Self::Create,
210 dbs::Action::Update => Self::Update,
211 dbs::Action::Delete => Self::Delete,
212 }
213 }
214}
215
216/// A live query notification
217///
218/// Live queries return a stream of notifications. The notification contains an `action` that triggered the change in the database record and `data` itself.
219/// For deletions the data is the record before it was deleted. For everything else, it's the newly created record or updated record depending on whether
220/// the action is create or update.
221#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
222#[non_exhaustive]
223pub struct Notification<R> {
224 pub action: Action,
225 pub data: R,
226}
227
228/// An error originating from the SurrealDB client library
229#[derive(Debug, thiserror::Error, serde::Serialize)]
230pub enum Error {
231 /// An error with an embedded storage engine
232 #[error("{0}")]
233 Db(#[from] crate::error::Db),
234 /// An error with a remote database instance
235 #[error("{0}")]
236 Api(#[from] crate::error::Api),
237}