surrealdb/api/method/
mod.rs

1//! Methods to use when interacting with a SurrealDB instance
2use self::query::ValidQuery;
3use crate::api::opt;
4use crate::api::opt::auth;
5use crate::api::opt::auth::Credentials;
6use crate::api::opt::auth::Jwt;
7use crate::api::opt::IntoEndpoint;
8use crate::api::Connect;
9use crate::api::Connection;
10use crate::api::OnceLockExt;
11use crate::api::Surreal;
12use crate::opt::IntoExportDestination;
13use crate::opt::WaitFor;
14use serde::Serialize;
15use std::borrow::Cow;
16use std::marker::PhantomData;
17use std::path::Path;
18use std::pin::Pin;
19use std::sync::Arc;
20use std::sync::OnceLock;
21use std::time::Duration;
22use surrealdb_core::sql::to_value as to_core_value;
23
24pub(crate) mod live;
25pub(crate) mod query;
26
27mod authenticate;
28mod begin;
29mod cancel;
30mod commit;
31mod content;
32mod create;
33mod delete;
34mod export;
35mod health;
36mod import;
37mod insert;
38mod insert_relation;
39mod invalidate;
40mod merge;
41mod patch;
42mod run;
43mod select;
44mod set;
45mod signin;
46mod signup;
47mod unset;
48mod update;
49mod upsert;
50mod use_db;
51mod use_ns;
52mod version;
53
54#[cfg(test)]
55mod tests;
56
57pub use authenticate::Authenticate;
58#[doc(hidden)] // Not supported yet
59pub use begin::Begin;
60#[doc(hidden)] // Not supported yet
61pub use begin::Transaction;
62#[doc(hidden)] // Not supported yet
63pub use cancel::Cancel;
64#[doc(hidden)] // Not supported yet
65pub use commit::Commit;
66pub use content::Content;
67pub use create::Create;
68pub use delete::Delete;
69pub use export::{Backup, Export};
70use futures::Future;
71pub use health::Health;
72pub use import::Import;
73pub use insert::Insert;
74pub use invalidate::Invalidate;
75pub use live::Stream;
76pub use merge::Merge;
77pub use patch::Patch;
78pub use query::Query;
79pub use query::QueryStream;
80pub use run::IntoFn;
81pub use run::Run;
82pub use select::Select;
83use serde_content::Serializer;
84pub use set::Set;
85pub use signin::Signin;
86pub use signup::Signup;
87use tokio::sync::watch;
88pub use unset::Unset;
89pub use update::Update;
90pub use upsert::Upsert;
91pub use use_db::UseDb;
92pub use use_ns::UseNs;
93pub use version::Version;
94
95use super::opt::IntoResource;
96
97/// A alias for an often used type of future returned by async methods in this library.
98pub(crate) type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
99
100/// Query statistics
101#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
102#[non_exhaustive]
103pub struct Stats {
104	/// The time taken to execute the query
105	pub execution_time: Option<Duration>,
106}
107
108/// Machine learning model marker type for import and export types
109pub struct Model;
110
111/// Live query marker type
112pub struct Live;
113
114/// Responses returned with statistics
115#[derive(Debug)]
116pub struct WithStats<T>(pub T);
117
118impl<C> Surreal<C>
119where
120	C: Connection,
121{
122	/// Initialises a new unconnected instance of the client
123	///
124	/// This makes it easy to create a static singleton of the client. The static singleton
125	/// pattern in the example below ensures that a single database instance is available
126	/// across very large or complicated applications. With the singleton, only one connection
127	/// to the database is instantiated, and the database connection does not have to be shared
128	/// across components or controllers.
129	///
130	/// # Examples
131	///
132	/// Using a static, compile-time scheme
133	///
134	/// ```no_run
135	/// use std::sync::LazyLock;
136	/// use serde::{Serialize, Deserialize};
137	/// use surrealdb::Surreal;
138	/// use surrealdb::opt::auth::Root;
139	/// use surrealdb::engine::remote::ws::Ws;
140	/// use surrealdb::engine::remote::ws::Client;
141	///
142	/// // Creates a new static instance of the client
143	/// static DB: LazyLock<Surreal<Client>> = LazyLock::new(Surreal::init);
144	///
145	/// #[derive(Serialize, Deserialize)]
146	/// struct Person {
147	///     name: String,
148	/// }
149	///
150	/// #[tokio::main]
151	/// async fn main() -> surrealdb::Result<()> {
152	///     // Connect to the database
153	///     DB.connect::<Ws>("localhost:8000").await?;
154	///
155	///     // Log into the database
156	///     DB.signin(Root {
157	///         username: "root",
158	///         password: "root",
159	///     }).await?;
160	///
161	///     // Select a namespace/database
162	///     DB.use_ns("namespace").use_db("database").await?;
163	///
164	///     // Create or update a specific record
165	///     let tobie: Option<Person> = DB.update(("person", "tobie"))
166	///         .content(Person {
167	///             name: "Tobie".into(),
168	///         }).await?;
169	///
170	///     Ok(())
171	/// }
172	/// ```
173	///
174	/// Using a dynamic, run-time scheme
175	///
176	/// ```no_run
177	/// use std::sync::LazyLock;
178	/// use serde::{Serialize, Deserialize};
179	/// use surrealdb::Surreal;
180	/// use surrealdb::engine::any::Any;
181	/// use surrealdb::opt::auth::Root;
182	///
183	/// // Creates a new static instance of the client
184	/// static DB: LazyLock<Surreal<Any>> = LazyLock::new(Surreal::init);
185	///
186	/// #[derive(Serialize, Deserialize)]
187	/// struct Person {
188	///     name: String,
189	/// }
190	///
191	/// #[tokio::main]
192	/// async fn main() -> surrealdb::Result<()> {
193	///     // Connect to the database
194	///     DB.connect("ws://localhost:8000").await?;
195	///
196	///     // Log into the database
197	///     DB.signin(Root {
198	///         username: "root",
199	///         password: "root",
200	///     }).await?;
201	///
202	///     // Select a namespace/database
203	///     DB.use_ns("namespace").use_db("database").await?;
204	///
205	///     // Create or update a specific record
206	///     let tobie: Option<Person> = DB.update(("person", "tobie"))
207	///         .content(Person {
208	///             name: "Tobie".into(),
209	///         }).await?;
210	///
211	///     Ok(())
212	/// }
213	/// ```
214	pub fn init() -> Self {
215		Self {
216			router: Arc::new(OnceLock::new()),
217			waiter: Arc::new(watch::channel(None)),
218			engine: PhantomData,
219		}
220	}
221
222	/// Connects to a local or remote database endpoint
223	///
224	/// # Examples
225	///
226	/// ```no_run
227	/// use surrealdb::Surreal;
228	/// use surrealdb::engine::remote::ws::{Ws, Wss};
229	///
230	/// # #[tokio::main]
231	/// # async fn main() -> surrealdb::Result<()> {
232	/// // Connect to a local endpoint
233	/// let db = Surreal::new::<Ws>("localhost:8000").await?;
234	///
235	/// // Connect to a remote endpoint
236	/// let db = Surreal::new::<Wss>("cloud.surrealdb.com").await?;
237	/// #
238	/// # Ok(())
239	/// # }
240	/// ```
241	pub fn new<P>(address: impl IntoEndpoint<P, Client = C>) -> Connect<C, Self> {
242		Connect {
243			router: Arc::new(OnceLock::new()),
244			engine: PhantomData,
245			address: address.into_endpoint(),
246			capacity: 0,
247			waiter: Arc::new(watch::channel(None)),
248			response_type: PhantomData,
249		}
250	}
251
252	#[doc(hidden)] // Not supported yet
253	pub fn transaction(self) -> Begin<C> {
254		Begin {
255			client: self,
256		}
257	}
258
259	/// Switch to a specific namespace
260	///
261	/// # Examples
262	///
263	/// ```no_run
264	/// # #[tokio::main]
265	/// # async fn main() -> surrealdb::Result<()> {
266	/// # let db = surrealdb::engine::any::connect("mem://").await?;
267	/// db.use_ns("namespace").await?;
268	/// # Ok(())
269	/// # }
270	/// ```
271	pub fn use_ns(&self, ns: impl Into<String>) -> UseNs<C> {
272		UseNs {
273			client: Cow::Borrowed(self),
274			ns: ns.into(),
275		}
276	}
277
278	/// Switch to a specific database
279	///
280	/// # Examples
281	///
282	/// ```no_run
283	/// # #[tokio::main]
284	/// # async fn main() -> surrealdb::Result<()> {
285	/// # let db = surrealdb::engine::any::connect("mem://").await?;
286	/// db.use_db("database").await?;
287	/// # Ok(())
288	/// # }
289	/// ```
290	pub fn use_db(&self, db: impl Into<String>) -> UseDb<C> {
291		UseDb {
292			client: Cow::Borrowed(self),
293			ns: None,
294			db: db.into(),
295		}
296	}
297
298	/// Assigns a value as a parameter for this connection
299	///
300	/// # Examples
301	///
302	/// ```no_run
303	/// use serde::Serialize;
304	///
305	/// #[derive(Serialize)]
306	/// struct Name {
307	///     first: String,
308	///     last: String,
309	/// }
310	///
311	/// # #[tokio::main]
312	/// # async fn main() -> surrealdb::Result<()> {
313	/// # let db = surrealdb::engine::any::connect("mem://").await?;
314	/// #
315	/// // Assign the variable on the connection
316	/// db.set("name", Name {
317	///     first: "Tobie".into(),
318	///     last: "Morgan Hitchcock".into(),
319	/// }).await?;
320	///
321	/// // Use the variable in a subsequent query
322	/// db.query("CREATE person SET name = $name").await?;
323	///
324	/// // Use the variable in a subsequent query
325	/// db.query("SELECT * FROM person WHERE name.first = $name.first").await?;
326	/// #
327	/// # Ok(())
328	/// # }
329	/// ```
330	pub fn set(&self, key: impl Into<String>, value: impl Serialize + 'static) -> Set<C> {
331		Set {
332			client: Cow::Borrowed(self),
333			key: key.into(),
334			value: to_core_value(value).map_err(Into::into),
335		}
336	}
337
338	/// Removes a parameter from this connection
339	///
340	/// # Examples
341	///
342	/// ```no_run
343	/// use serde::Serialize;
344	///
345	/// #[derive(Serialize)]
346	/// struct Name {
347	///     first: String,
348	///     last: String,
349	/// }
350	///
351	/// # #[tokio::main]
352	/// # async fn main() -> surrealdb::Result<()> {
353	/// # let db = surrealdb::engine::any::connect("mem://").await?;
354	/// #
355	/// // Assign the variable on the connection
356	/// db.set("name", Name {
357	///     first: "Tobie".into(),
358	///     last: "Morgan Hitchcock".into(),
359	/// }).await?;
360	///
361	/// // Use the variable in a subsequent query
362	/// db.query("CREATE person SET name = $name").await?;
363	///
364	/// // Remove the variable from the connection
365	/// db.unset("name").await?;
366	/// #
367	/// # Ok(())
368	/// # }
369	/// ```
370	pub fn unset(&self, key: impl Into<String>) -> Unset<C> {
371		Unset {
372			client: Cow::Borrowed(self),
373			key: key.into(),
374		}
375	}
376
377	/// Signs up a user with a specific record access method
378	///
379	/// # Examples
380	///
381	/// ```no_run
382	/// use serde::Serialize;
383	/// use surrealdb::sql;
384	/// use surrealdb::opt::auth::Root;
385	/// use surrealdb::opt::auth::Record;
386	///
387	/// #[derive(Debug, Serialize)]
388	/// struct AuthParams {
389	///     email: String,
390	///     password: String,
391	/// }
392	///
393	/// # #[tokio::main]
394	/// # async fn main() -> surrealdb::Result<()> {
395	/// # let db = surrealdb::engine::any::connect("mem://").await?;
396	/// #
397	/// // Sign in as root
398	/// db.signin(Root {
399	///     username: "root",
400	///     password: "root",
401	/// })
402	/// .await?;
403	///
404	/// // Select the namespace/database to use
405	/// db.use_ns("namespace").use_db("database").await?;
406	///
407	/// // Define the user record access
408	/// let sql = r#"
409	///     DEFINE ACCESS user_access ON DATABASE TYPE RECORD DURATION 24h
410	///     SIGNUP ( CREATE user SET email = $email, password = crypto::argon2::generate($password) )
411	///     SIGNIN ( SELECT * FROM user WHERE email = $email AND crypto::argon2::compare(password, $password) )
412	/// "#;
413	/// db.query(sql).await?.check()?;
414	///
415	/// // Sign a user up
416	/// db.signup(Record {
417	///     namespace: "namespace",
418	///     database: "database",
419	///     access: "user_access",
420	///     params: AuthParams {
421	///         email: "john.doe@example.com".into(),
422	///         password: "password123".into(),
423	///     },
424	/// }).await?;
425	/// #
426	/// # Ok(())
427	/// # }
428	/// ```
429	pub fn signup<R>(&self, credentials: impl Credentials<auth::Signup, R>) -> Signup<C, R> {
430		Signup {
431			client: Cow::Borrowed(self),
432			credentials: Serializer::new().serialize(credentials),
433			response_type: PhantomData,
434		}
435	}
436
437	/// Signs this connection in to a specific authentication level
438	///
439	/// # Examples
440	///
441	/// Namespace signin
442	///
443	/// ```no_run
444	/// use surrealdb::sql;
445	/// use surrealdb::opt::auth::Root;
446	/// use surrealdb::opt::auth::Namespace;
447	///
448	/// # #[tokio::main]
449	/// # async fn main() -> surrealdb::Result<()> {
450	/// # let db = surrealdb::engine::any::connect("mem://").await?;
451	/// #
452	/// // Sign in as root
453	/// db.signin(Root {
454	///     username: "root",
455	///     password: "root",
456	/// })
457	/// .await?;
458	///
459	/// // Select the namespace/database to use
460	/// db.use_ns("namespace").use_db("database").await?;
461	///
462	/// // Define the user
463	/// let sql = "DEFINE USER johndoe ON NAMESPACE PASSWORD 'password123'";
464	/// db.query(sql).await?.check()?;
465	///
466	/// // Sign a user in
467	/// db.signin(Namespace {
468	///     namespace: "namespace",
469	///     username: "johndoe",
470	///     password: "password123",
471	/// }).await?;
472	/// #
473	/// # Ok(())
474	/// # }
475	/// ```
476	///
477	/// Database signin
478	///
479	/// ```no_run
480	/// use surrealdb::sql;
481	/// use surrealdb::opt::auth::Root;
482	/// use surrealdb::opt::auth::Database;
483	///
484	/// # #[tokio::main]
485	/// # async fn main() -> surrealdb::Result<()> {
486	/// # let db = surrealdb::engine::any::connect("mem://").await?;
487	/// #
488	/// // Sign in as root
489	/// db.signin(Root {
490	///     username: "root",
491	///     password: "root",
492	/// })
493	/// .await?;
494	///
495	/// // Select the namespace/database to use
496	/// db.use_ns("namespace").use_db("database").await?;
497	///
498	/// // Define the user
499	/// let sql = "DEFINE USER johndoe ON DATABASE PASSWORD 'password123'";
500	/// db.query(sql).await?.check()?;
501	///
502	/// // Sign a user in
503	/// db.signin(Database {
504	///     namespace: "namespace",
505	///     database: "database",
506	///     username: "johndoe",
507	///     password: "password123",
508	/// }).await?;
509	/// #
510	/// # Ok(())
511	/// # }
512	/// ```
513	///
514	/// Record signin
515	///
516	/// ```no_run
517	/// use serde::Serialize;
518	/// use surrealdb::opt::auth::Root;
519	/// use surrealdb::opt::auth::Record;
520	///
521	/// #[derive(Debug, Serialize)]
522	/// struct AuthParams {
523	///     email: String,
524	///     password: String,
525	/// }
526	///
527	/// # #[tokio::main]
528	/// # async fn main() -> surrealdb::Result<()> {
529	/// # let db = surrealdb::engine::any::connect("mem://").await?;
530	/// #
531	/// // Select the namespace/database to use
532	/// db.use_ns("namespace").use_db("database").await?;
533	///
534	/// // Sign a user in
535	/// db.signin(Record {
536	///     namespace: "namespace",
537	///     database: "database",
538	///     access: "user_access",
539	///     params: AuthParams {
540	///         email: "john.doe@example.com".into(),
541	///         password: "password123".into(),
542	///     },
543	/// }).await?;
544	/// #
545	/// # Ok(())
546	/// # }
547	/// ```
548	pub fn signin<R>(&self, credentials: impl Credentials<auth::Signin, R>) -> Signin<C, R> {
549		Signin {
550			client: Cow::Borrowed(self),
551			credentials: Serializer::new().serialize(credentials),
552			response_type: PhantomData,
553		}
554	}
555
556	/// Invalidates the authentication for the current connection
557	///
558	/// # Examples
559	///
560	/// ```no_run
561	/// # #[tokio::main]
562	/// # async fn main() -> surrealdb::Result<()> {
563	/// # let db = surrealdb::engine::any::connect("mem://").await?;
564	/// db.invalidate().await?;
565	/// # Ok(())
566	/// # }
567	/// ```
568	pub fn invalidate(&self) -> Invalidate<C> {
569		Invalidate {
570			client: Cow::Borrowed(self),
571		}
572	}
573
574	/// Authenticates the current connection with a JWT token
575	///
576	/// # Examples
577	///
578	/// ```no_run
579	/// # #[tokio::main]
580	/// # async fn main() -> surrealdb::Result<()> {
581	/// # let db = surrealdb::engine::any::connect("mem://").await?;
582	/// # let token = String::new();
583	/// db.authenticate(token).await?;
584	/// # Ok(())
585	/// # }
586	/// ```
587	pub fn authenticate(&self, token: impl Into<Jwt>) -> Authenticate<C> {
588		Authenticate {
589			client: Cow::Borrowed(self),
590			token: token.into(),
591		}
592	}
593
594	/// Runs a set of SurrealQL statements against the database
595	///
596	/// # Examples
597	///
598	/// ```no_run
599	/// use surrealdb::sql;
600	///
601	/// # #[derive(serde::Deserialize)]
602	/// # struct Person;
603	/// # #[tokio::main]
604	/// # async fn main() -> surrealdb::Result<()> {
605	/// # let db = surrealdb::engine::any::connect("mem://").await?;
606	/// #
607	/// // Select the namespace/database to use
608	/// db.use_ns("namespace").use_db("database").await?;
609	///
610	/// // Run queries
611	/// let mut result = db
612	///     .query("CREATE person")
613	///     .query("SELECT * FROM type::table($table)")
614	///     .bind(("table", "person"))
615	///     .await?;
616	///
617	/// // Get the first result from the first query
618	/// let created: Option<Person> = result.take(0)?;
619	///
620	/// // Get all of the results from the second query
621	/// let people: Vec<Person> = result.take(1)?;
622	///
623	/// #[derive(serde::Deserialize)]
624	/// struct Country {
625	///     name: String
626	/// }
627	///
628	/// // The .take() method can be used for error handling
629	///
630	/// // If the table has no defined schema, this query will
631	/// // create a `country` on the SurrealDB side, but...
632	/// let mut result = db
633	///     .query("CREATE country")
634	///     .await?;
635	///
636	/// // It won't deserialize into a Country struct
637	/// if let Err(e) = result.take::<Option<Country>>(0) {
638	///     println!("Failed to make a country: {e:#?}");
639	///     assert!(e.to_string().contains("missing field `name`"));
640	/// }
641	/// #
642	/// # Ok(())
643	/// # }
644	/// ```
645	pub fn query(&self, query: impl opt::IntoQuery) -> Query<C> {
646		let inner = query.into_query().map(|x| ValidQuery {
647			client: Cow::Borrowed(self),
648			query: x,
649			bindings: Default::default(),
650			register_live_queries: true,
651		});
652
653		Query {
654			inner,
655		}
656	}
657
658	/// Selects all records in a table, or a specific record
659	///
660	/// # Examples
661	///
662	/// ```no_run
663	/// # use futures::StreamExt;
664	/// # use surrealdb::opt::Resource;
665	/// # #[derive(serde::Deserialize)]
666	/// # struct Person;
667	/// #
668	/// # #[tokio::main]
669	/// # async fn main() -> surrealdb::Result<()> {
670	/// # let db = surrealdb::engine::any::connect("mem://").await?;
671	/// #
672	/// // Select the namespace/database to use
673	/// db.use_ns("namespace").use_db("database").await?;
674	///
675	/// // Select all records from a table
676	/// let people: Vec<Person> = db.select("person").await?;
677	///
678	/// // Select a range of records from a table
679	/// let people: Vec<Person> = db.select("person").range("jane".."john").await?;
680	///
681	/// // Select a specific record from a table
682	/// let person: Option<Person> = db.select(("person", "h5wxrf2ewk8xjxosxtyc")).await?;
683	///
684	/// // To listen for updates as they happen on a record, a range of records
685	/// // or entire table use a live query. This is done by simply calling `.live()`
686	/// // after this method. That gives you a stream of notifications you can listen on.
687	/// # let resource = Resource::from("person");
688	/// let mut stream = db.select(resource).live().await?;
689	///
690	/// while let Some(notification) = stream.next().await {
691	///     // Use the notification
692	/// }
693	/// #
694	/// # Ok(())
695	/// # }
696	/// ```
697	pub fn select<O>(&self, resource: impl IntoResource<O>) -> Select<C, O> {
698		Select {
699			client: Cow::Borrowed(self),
700			resource: resource.into_resource(),
701			response_type: PhantomData,
702			query_type: PhantomData,
703		}
704	}
705
706	/// Creates a record in the database
707	///
708	/// # Examples
709	///
710	/// ```no_run
711	/// use serde::Serialize;
712	///
713	/// # #[derive(serde::Deserialize)]
714	/// # struct Person;
715	/// #
716	/// #[derive(Serialize)]
717	/// struct Settings {
718	///     active: bool,
719	///     marketing: bool,
720	/// }
721	///
722	/// #[derive(Serialize)]
723	/// struct User {
724	///     name: &'static str,
725	///     settings: Settings,
726	/// }
727	///
728	/// # #[tokio::main]
729	/// # async fn main() -> surrealdb::Result<()> {
730	/// # let db = surrealdb::engine::any::connect("mem://").await?;
731	/// #
732	/// // Select the namespace/database to use
733	/// db.use_ns("namespace").use_db("database").await?;
734	///
735	/// // Create a record with a random ID
736	/// let person: Option<Person> = db.create("person").await?;
737	///
738	/// // Create a record with a specific ID
739	/// let record: Option<Person> = db.create(("person", "tobie"))
740	///     .content(User {
741	///         name: "Tobie",
742	///         settings: Settings {
743	///             active: true,
744	///             marketing: true,
745	///         },
746	///     })
747	///     .await?;
748	/// #
749	/// # Ok(())
750	/// # }
751	/// ```
752	pub fn create<R>(&self, resource: impl IntoResource<R>) -> Create<C, R> {
753		Create {
754			client: Cow::Borrowed(self),
755			resource: resource.into_resource(),
756			response_type: PhantomData,
757		}
758	}
759
760	/// Insert a record or records into a table
761	///
762	/// # Examples
763	///
764	/// ```no_run
765	/// use serde::{Serialize, Deserialize};
766	/// use surrealdb::sql;
767	///
768	/// # #[derive(Deserialize)]
769	/// # struct Person;
770	/// #
771	/// #[derive(Serialize)]
772	/// struct Settings {
773	///     active: bool,
774	///     marketing: bool,
775	/// }
776	///
777	/// #[derive(Serialize)]
778	/// struct User<'a> {
779	///     name: &'a str,
780	///     settings: Settings,
781	/// }
782	///
783	/// # #[tokio::main]
784	/// # async fn main() -> surrealdb::Result<()> {
785	/// # let db = surrealdb::engine::any::connect("mem://").await?;
786	/// #
787	/// // Select the namespace/database to use
788	/// db.use_ns("namespace").use_db("database").await?;
789	///
790	/// // Insert a record with a specific ID
791	/// let person: Option<Person> = db.insert(("person", "tobie"))
792	///     .content(User {
793	///         name: "Tobie",
794	///         settings: Settings {
795	///             active: true,
796	///             marketing: true,
797	///         },
798	///     })
799	///     .await?;
800	///
801	/// // Insert multiple records into the table
802	/// let people: Vec<Person> = db.insert("person")
803	///     .content(vec![
804	///         User {
805	///             name: "Tobie",
806	///             settings: Settings {
807	///                 active: true,
808	///                 marketing: false,
809	///             },
810	///         },
811	///         User {
812	///             name: "Jaime",
813	///             settings: Settings {
814	///                 active: true,
815	///                 marketing: true,
816	///             },
817	///         },
818	///     ])
819	///     .await?;
820	///
821	/// // Insert multiple records with pre-defined IDs
822	/// #[derive(Serialize)]
823	/// struct UserWithId<'a> {
824	///     id: sql::Thing,
825	///     name: &'a str,
826	///     settings: Settings,
827	/// }
828	///
829	/// let people: Vec<Person> = db.insert("person")
830	///     .content(vec![
831	///         UserWithId {
832	///             id: sql::thing("person:tobie")?,
833	///             name: "Tobie",
834	///             settings: Settings {
835	///                 active: true,
836	///                 marketing: false,
837	///             },
838	///         },
839	///         UserWithId {
840	///             id: sql::thing("person:jaime")?,
841	///             name: "Jaime",
842	///             settings: Settings {
843	///                 active: true,
844	///                 marketing: true,
845	///             },
846	///         },
847	///     ])
848	///     .await?;
849	///
850	/// // Insert multiple records into different tables
851	/// #[derive(Serialize)]
852	/// struct WithId<'a> {
853	///     id: sql::Thing,
854	///     name: &'a str,
855	/// }
856	///
857	/// let people: Vec<Person> = db.insert(())
858	///     .content(vec![
859	///         WithId {
860	///             id: sql::thing("person:tobie")?,
861	///             name: "Tobie",
862	///         },
863	///         WithId {
864	///             id: sql::thing("company:surrealdb")?,
865	///             name: "SurrealDB",
866	///         },
867	///     ])
868	///     .await?;
869	///
870	///
871	/// // Insert relations
872	/// #[derive(Serialize, Deserialize)]
873	/// struct Founded {
874	///     #[serde(rename = "in")]
875	///     founder: sql::Thing,
876	///     #[serde(rename = "out")]
877	///     company: sql::Thing,
878	/// }
879	///
880	/// let founded: Vec<Founded> = db.insert("founded")
881	///     .relation(vec![
882	///         Founded {
883	///             founder: sql::thing("person:tobie")?,
884	///             company: sql::thing("company:surrealdb")?,
885	///         },
886	///         Founded {
887	///             founder: sql::thing("person:jaime")?,
888	///             company: sql::thing("company:surrealdb")?,
889	///         },
890	///     ])
891	///     .await?;
892	///
893	/// #
894	/// # Ok(())
895	/// # }
896	/// ```
897	pub fn insert<O>(&self, resource: impl IntoResource<O>) -> Insert<C, O> {
898		Insert {
899			client: Cow::Borrowed(self),
900			resource: resource.into_resource(),
901			response_type: PhantomData,
902		}
903	}
904
905	/// Updates all records in a table, or a specific record
906	///
907	/// # Examples
908	///
909	/// Replace the current document / record data with the specified data.
910	///
911	/// ```no_run
912	/// use serde::Serialize;
913	///
914	/// # #[derive(serde::Deserialize)]
915	/// # struct Person;
916	/// #
917	/// #[derive(Serialize)]
918	/// struct Settings {
919	///     active: bool,
920	///     marketing: bool,
921	/// }
922	///
923	/// #[derive(Serialize)]
924	/// struct User {
925	///     name: &'static str,
926	///     settings: Settings,
927	/// }
928	///
929	/// # #[tokio::main]
930	/// # async fn main() -> surrealdb::Result<()> {
931	/// # let db = surrealdb::engine::any::connect("mem://").await?;
932	/// #
933	/// // Select the namespace/database to use
934	/// db.use_ns("namespace").use_db("database").await?;
935	///
936	/// // Update all records in a table
937	/// let people: Vec<Person> = db.upsert("person").await?;
938	///
939	/// // Update a record with a specific ID
940	/// let person: Option<Person> = db.upsert(("person", "tobie"))
941	///     .content(User {
942	///         name: "Tobie",
943	///         settings: Settings {
944	///             active: true,
945	///             marketing: true,
946	///         },
947	///     })
948	///     .await?;
949	/// #
950	/// # Ok(())
951	/// # }
952	/// ```
953	///
954	/// Merge the current document / record data with the specified data.
955	///
956	/// ```no_run
957	/// use serde::Serialize;
958	/// use time::OffsetDateTime;
959	///
960	/// # #[derive(serde::Deserialize)]
961	/// # struct Person;
962	/// #
963	/// #[derive(Serialize)]
964	/// struct UpdatedAt {
965	///     updated_at: OffsetDateTime,
966	/// }
967	///
968	/// #[derive(Serialize)]
969	/// struct Settings {
970	///     active: bool,
971	/// }
972	///
973	/// #[derive(Serialize)]
974	/// struct User {
975	///     updated_at: OffsetDateTime,
976	///     settings: Settings,
977	/// }
978	///
979	/// # #[tokio::main]
980	/// # async fn main() -> surrealdb::Result<()> {
981	/// # let db = surrealdb::engine::any::connect("mem://").await?;
982	/// #
983	/// // Select the namespace/database to use
984	/// db.use_ns("namespace").use_db("database").await?;
985	///
986	/// // Update all records in a table
987	/// let people: Vec<Person> = db.upsert("person")
988	///     .merge(UpdatedAt {
989	///         updated_at: OffsetDateTime::now_utc(),
990	///     })
991	///     .await?;
992	///
993	/// // Update a record with a specific ID
994	/// let person: Option<Person> = db.upsert(("person", "tobie"))
995	///     .merge(User {
996	///         updated_at: OffsetDateTime::now_utc(),
997	///         settings: Settings {
998	///             active: true,
999	///         },
1000	///     })
1001	///     .await?;
1002	/// #
1003	/// # Ok(())
1004	/// # }
1005	/// ```
1006	///
1007	/// Apply [JSON Patch](https://jsonpatch.com) changes to all records, or a specific record, in the database.
1008	///
1009	/// ```no_run
1010	/// use serde::Serialize;
1011	/// use surrealdb::opt::PatchOp;
1012	/// use time::OffsetDateTime;
1013	///
1014	/// # #[derive(serde::Deserialize)]
1015	/// # struct Person;
1016	/// #
1017	/// #[derive(Serialize)]
1018	/// struct UpdatedAt {
1019	///     updated_at: OffsetDateTime,
1020	/// }
1021	///
1022	/// #[derive(Serialize)]
1023	/// struct Settings {
1024	///     active: bool,
1025	/// }
1026	///
1027	/// #[derive(Serialize)]
1028	/// struct User {
1029	///     updated_at: OffsetDateTime,
1030	///     settings: Settings,
1031	/// }
1032	///
1033	/// # #[tokio::main]
1034	/// # async fn main() -> surrealdb::Result<()> {
1035	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1036	/// #
1037	/// // Select the namespace/database to use
1038	/// db.use_ns("namespace").use_db("database").await?;
1039	///
1040	/// // Update all records in a table
1041	/// let people: Vec<Person> = db.upsert("person")
1042	///     .patch(PatchOp::replace("/created_at", OffsetDateTime::now_utc()))
1043	///     .await?;
1044	///
1045	/// // Update a record with a specific ID
1046	/// let person: Option<Person> = db.upsert(("person", "tobie"))
1047	///     .patch(PatchOp::replace("/settings/active", false))
1048	///     .patch(PatchOp::add("/tags", ["developer", "engineer"]))
1049	///     .patch(PatchOp::remove("/temp"))
1050	///     .await?;
1051	/// #
1052	/// # Ok(())
1053	/// # }
1054	/// ```
1055	pub fn upsert<O>(&self, resource: impl IntoResource<O>) -> Upsert<C, O> {
1056		Upsert {
1057			client: Cow::Borrowed(self),
1058			resource: resource.into_resource(),
1059			response_type: PhantomData,
1060		}
1061	}
1062
1063	/// Updates all records in a table, or a specific record
1064	///
1065	/// # Examples
1066	///
1067	/// Replace the current document / record data with the specified data.
1068	///
1069	/// ```no_run
1070	/// use serde::Serialize;
1071	///
1072	/// # #[derive(serde::Deserialize)]
1073	/// # struct Person;
1074	/// #
1075	/// #[derive(Serialize)]
1076	/// struct Settings {
1077	///     active: bool,
1078	///     marketing: bool,
1079	/// }
1080	///
1081	/// #[derive(Serialize)]
1082	/// struct User {
1083	///     name: &'static str,
1084	///     settings: Settings,
1085	/// }
1086	///
1087	/// # #[tokio::main]
1088	/// # async fn main() -> surrealdb::Result<()> {
1089	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1090	/// #
1091	/// // Select the namespace/database to use
1092	/// db.use_ns("namespace").use_db("database").await?;
1093	///
1094	/// // Update all records in a table
1095	/// let people: Vec<Person> = db.update("person").await?;
1096	///
1097	/// // Update a record with a specific ID
1098	/// let person: Option<Person> = db.update(("person", "tobie"))
1099	///     .content(User {
1100	///         name: "Tobie",
1101	///         settings: Settings {
1102	///             active: true,
1103	///             marketing: true,
1104	///         },
1105	///     })
1106	///     .await?;
1107	/// #
1108	/// # Ok(())
1109	/// # }
1110	/// ```
1111	///
1112	/// Merge the current document / record data with the specified data.
1113	///
1114	/// ```no_run
1115	/// use serde::Serialize;
1116	/// use time::OffsetDateTime;
1117	///
1118	/// # #[derive(serde::Deserialize)]
1119	/// # struct Person;
1120	/// #
1121	/// #[derive(Serialize)]
1122	/// struct UpdatedAt {
1123	///     updated_at: OffsetDateTime,
1124	/// }
1125	///
1126	/// #[derive(Serialize)]
1127	/// struct Settings {
1128	///     active: bool,
1129	/// }
1130	///
1131	/// #[derive(Serialize)]
1132	/// struct User {
1133	///     updated_at: OffsetDateTime,
1134	///     settings: Settings,
1135	/// }
1136	///
1137	/// # #[tokio::main]
1138	/// # async fn main() -> surrealdb::Result<()> {
1139	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1140	/// #
1141	/// // Select the namespace/database to use
1142	/// db.use_ns("namespace").use_db("database").await?;
1143	///
1144	/// // Update all records in a table
1145	/// let people: Vec<Person> = db.update("person")
1146	///     .merge(UpdatedAt {
1147	///         updated_at: OffsetDateTime::now_utc(),
1148	///     })
1149	///     .await?;
1150	///
1151	/// // Update a record with a specific ID
1152	/// let person: Option<Person> = db.update(("person", "tobie"))
1153	///     .merge(User {
1154	///         updated_at: OffsetDateTime::now_utc(),
1155	///         settings: Settings {
1156	///             active: true,
1157	///         },
1158	///     })
1159	///     .await?;
1160	/// #
1161	/// # Ok(())
1162	/// # }
1163	/// ```
1164	///
1165	/// Apply [JSON Patch](https://jsonpatch.com) changes to all records, or a specific record, in the database.
1166	///
1167	/// ```no_run
1168	/// use serde::Serialize;
1169	/// use surrealdb::opt::PatchOp;
1170	/// use time::OffsetDateTime;
1171	///
1172	/// # #[derive(serde::Deserialize)]
1173	/// # struct Person;
1174	/// #
1175	/// #[derive(Serialize)]
1176	/// struct UpdatedAt {
1177	///     updated_at: OffsetDateTime,
1178	/// }
1179	///
1180	/// #[derive(Serialize)]
1181	/// struct Settings {
1182	///     active: bool,
1183	/// }
1184	///
1185	/// #[derive(Serialize)]
1186	/// struct User {
1187	///     updated_at: OffsetDateTime,
1188	///     settings: Settings,
1189	/// }
1190	///
1191	/// # #[tokio::main]
1192	/// # async fn main() -> surrealdb::Result<()> {
1193	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1194	/// #
1195	/// // Select the namespace/database to use
1196	/// db.use_ns("namespace").use_db("database").await?;
1197	///
1198	/// // Update all records in a table
1199	/// let people: Vec<Person> = db.update("person")
1200	///     .patch(PatchOp::replace("/created_at", OffsetDateTime::now_utc()))
1201	///     .await?;
1202	///
1203	/// // Update a record with a specific ID
1204	/// let person: Option<Person> = db.update(("person", "tobie"))
1205	///     .patch(PatchOp::replace("/settings/active", false))
1206	///     .patch(PatchOp::add("/tags", ["developer", "engineer"]))
1207	///     .patch(PatchOp::remove("/temp"))
1208	///     .await?;
1209	/// #
1210	/// # Ok(())
1211	/// # }
1212	/// ```
1213	pub fn update<O>(&self, resource: impl IntoResource<O>) -> Update<C, O> {
1214		Update {
1215			client: Cow::Borrowed(self),
1216			resource: resource.into_resource(),
1217			response_type: PhantomData,
1218		}
1219	}
1220
1221	/// Deletes all records, or a specific record
1222	///
1223	/// # Examples
1224	///
1225	/// ```no_run
1226	/// # #[derive(serde::Deserialize)]
1227	/// # struct Person;
1228	/// #
1229	/// # #[tokio::main]
1230	/// # async fn main() -> surrealdb::Result<()> {
1231	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1232	/// #
1233	/// // Select the namespace/database to use
1234	/// db.use_ns("namespace").use_db("database").await?;
1235	///
1236	/// // Delete all records from a table
1237	/// let people: Vec<Person> = db.delete("person").await?;
1238	///
1239	/// // Delete a specific record from a table
1240	/// let person: Option<Person> = db.delete(("person", "h5wxrf2ewk8xjxosxtyc")).await?;
1241	/// #
1242	/// # Ok(())
1243	/// # }
1244	/// ```
1245	pub fn delete<O>(&self, resource: impl IntoResource<O>) -> Delete<C, O> {
1246		Delete {
1247			client: Cow::Borrowed(self),
1248			resource: resource.into_resource(),
1249			response_type: PhantomData,
1250		}
1251	}
1252
1253	/// Returns the version of the server
1254	///
1255	/// # Examples
1256	///
1257	/// ```no_run
1258	/// # #[tokio::main]
1259	/// # async fn main() -> surrealdb::Result<()> {
1260	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1261	/// let version = db.version().await?;
1262	/// # Ok(())
1263	/// # }
1264	/// ```
1265	pub fn version(&self) -> Version<C> {
1266		Version {
1267			client: Cow::Borrowed(self),
1268		}
1269	}
1270
1271	/// Runs a function
1272	///
1273	/// # Examples
1274	///
1275	/// ```no_run
1276	/// # #[tokio::main]
1277	/// # async fn main() -> surrealdb::Result<()> {
1278	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1279	/// // Specify no args by not calling `.args()`
1280	/// let foo = db.run("fn::foo").await?; // fn::foo()
1281	/// // A single value will be turned into one argument
1282	/// let bar = db.run("fn::bar").args(42).await?; // fn::bar(42)
1283	/// // Arrays are treated as single arguments
1284	/// let count = db.run("count").args(vec![1,2,3]).await?;
1285	/// // Specify multiple args using a tuple
1286	/// let two = db.run("math::log").args((100, 10)).await?; // math::log(100, 10)
1287	///
1288	/// # Ok(())
1289	/// # }
1290	/// ```
1291	///
1292	pub fn run<R>(&self, function: impl IntoFn) -> Run<C, R> {
1293		Run {
1294			client: Cow::Borrowed(self),
1295			function: function.into_fn(),
1296			args: Ok(serde_content::Value::Tuple(vec![])),
1297			response_type: PhantomData,
1298		}
1299	}
1300
1301	/// Checks whether the server is healthy or not
1302	///
1303	/// # Examples
1304	///
1305	/// ```no_run
1306	/// # #[tokio::main]
1307	/// # async fn main() -> surrealdb::Result<()> {
1308	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1309	/// db.health().await?;
1310	/// # Ok(())
1311	/// # }
1312	/// ```
1313	pub fn health(&self) -> Health<C> {
1314		Health {
1315			client: Cow::Borrowed(self),
1316		}
1317	}
1318
1319	/// Wait for the selected event to happen before proceeding
1320	pub async fn wait_for(&self, event: WaitFor) {
1321		let mut rx = self.waiter.0.subscribe();
1322		rx.wait_for(|current| match current {
1323			// The connection hasn't been initialised yet.
1324			None => false,
1325			// The connection has been initialised. Only the connection even matches.
1326			Some(WaitFor::Connection) => matches!(event, WaitFor::Connection),
1327			// The database has been selected. Connection and database events both match.
1328			Some(WaitFor::Database) => matches!(event, WaitFor::Connection | WaitFor::Database),
1329		})
1330		.await
1331		.ok();
1332	}
1333
1334	/// Dumps the database contents to a file
1335	///
1336	/// # Support
1337	///
1338	/// Currently only supported by HTTP and the local engines. *Not* supported on WebAssembly.
1339	///
1340	/// # Examples
1341	///
1342	/// ```no_run
1343	/// # use futures::StreamExt;
1344	/// # #[tokio::main]
1345	/// # async fn main() -> surrealdb::Result<()> {
1346	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1347	/// // Select the namespace/database to use
1348	/// db.use_ns("namespace").use_db("database").await?;
1349	///
1350	/// // Export to a file
1351	/// db.export("backup.sql").await?;
1352	///
1353	/// // Export to a stream of bytes
1354	/// let mut backup = db.export(()).await?;
1355	/// while let Some(result) = backup.next().await {
1356	///     match result {
1357	///         Ok(bytes) => {
1358	///             // Do something with the bytes received...
1359	///         }
1360	///         Err(error) => {
1361	///             // Handle the export error
1362	///         }
1363	///     }
1364	/// }
1365	/// # Ok(())
1366	/// # }
1367	/// ```
1368	pub fn export<R>(&self, target: impl IntoExportDestination<R>) -> Export<C, R> {
1369		Export {
1370			client: Cow::Borrowed(self),
1371			target: target.into_export_destination(),
1372			ml_config: None,
1373			response: PhantomData,
1374			export_type: PhantomData,
1375		}
1376	}
1377
1378	/// Restores the database from a file
1379	///
1380	/// # Support
1381	///
1382	/// Currently only supported by HTTP and the local engines. *Not* supported on WebAssembly.
1383	///
1384	/// # Examples
1385	///
1386	/// ```no_run
1387	/// # #[tokio::main]
1388	/// # async fn main() -> surrealdb::Result<()> {
1389	/// # let db = surrealdb::engine::any::connect("mem://").await?;
1390	/// // Select the namespace/database to use
1391	/// db.use_ns("namespace").use_db("database").await?;
1392	///
1393	/// db.import("backup.sql").await?;
1394	/// # Ok(())
1395	/// # }
1396	/// ```
1397	pub fn import<P>(&self, file: P) -> Import<C>
1398	where
1399		P: AsRef<Path>,
1400	{
1401		Import {
1402			client: Cow::Borrowed(self),
1403			file: file.as_ref().to_owned(),
1404			is_ml: false,
1405			import_type: PhantomData,
1406		}
1407	}
1408}