From ffc3ed82f77d5afc6f3ff4cf37e046af464b8afe Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Tue, 3 May 2022 21:20:36 +0100 Subject: [PATCH] Simplify external API when working with Datastore --- lib/src/dbs/dbs.rs | 55 ----- lib/src/dbs/executor.rs | 10 +- lib/src/dbs/mod.rs | 2 - lib/src/dbs/session.rs | 18 +- lib/src/dbs/test.rs | 5 +- lib/src/dbs/variables.rs | 8 +- lib/src/kvs/ds.rs | 186 ++++++++++++++ lib/src/kvs/ex.rs | 285 --------------------- lib/src/kvs/kv.rs | 28 +++ lib/src/kvs/mod.rs | 97 +------- lib/src/kvs/tx.rs | 521 +++++++++++++++++++++++++++++++++------ lib/src/lib.rs | 2 - src/net/conf.rs | 3 +- src/net/key.rs | 32 +-- src/net/sql.rs | 4 +- 15 files changed, 702 insertions(+), 554 deletions(-) delete mode 100644 lib/src/dbs/dbs.rs create mode 100644 lib/src/kvs/ds.rs delete mode 100644 lib/src/kvs/ex.rs diff --git a/lib/src/dbs/dbs.rs b/lib/src/dbs/dbs.rs deleted file mode 100644 index 7ecb43a7..00000000 --- a/lib/src/dbs/dbs.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::dbs::Attach; -use crate::dbs::Executor; -use crate::dbs::Options; -use crate::dbs::Response; -use crate::dbs::Session; -use crate::dbs::Variables; -use crate::err::Error; -use crate::kvs::Store; -use crate::sql; -use crate::sql::query::Query; -use std::sync::Arc; - -pub async fn execute( - kvs: Store, - txt: &str, - session: Session, - vars: Variables, -) -> Result, Error> { - // Create a new query options - let mut opt = Options::default(); - // Create a new query executor - let mut exe = Executor::new(kvs); - // Create a new execution context - let ctx = session.context(); - // Attach the defined variables - let ctx = vars.attach(ctx); - // Parse the SQL query text - let ast = sql::parse(txt)?; - // Process all statements - opt.auth = Arc::new(session.au); - opt.ns = session.ns.map(Arc::new); - opt.db = session.db.map(Arc::new); - exe.execute(ctx, opt, ast).await -} - -pub async fn process( - kvs: Store, - ast: Query, - session: Session, - vars: Variables, -) -> Result, Error> { - // Create a new query options - let mut opt = Options::default(); - // Create a new query executor - let mut exe = Executor::new(kvs); - // Store session info on context - let ctx = session.context(); - // Attach the defined variables - let ctx = vars.attach(ctx); - // Process all statements - opt.auth = Arc::new(session.au); - opt.ns = session.ns.map(Arc::new); - opt.db = session.db.map(Arc::new); - exe.execute(ctx, opt, ast).await -} diff --git a/lib/src/dbs/executor.rs b/lib/src/dbs/executor.rs index 5a9a1c81..07824f75 100644 --- a/lib/src/dbs/executor.rs +++ b/lib/src/dbs/executor.rs @@ -6,7 +6,7 @@ use crate::dbs::Options; use crate::dbs::Runtime; use crate::dbs::Transaction; use crate::err::Error; -use crate::kvs::Store; +use crate::kvs::Datastore; use crate::sql::query::Query; use crate::sql::statement::Statement; use crate::sql::value::Value; @@ -14,14 +14,14 @@ use futures::lock::Mutex; use std::sync::Arc; use trice::Instant; -pub struct Executor { +pub struct Executor<'a> { err: bool, - kvs: Store, + kvs: &'a Datastore, txn: Option, } -impl Executor { - pub fn new(kvs: Store) -> Executor { +impl<'a> Executor<'a> { + pub fn new(kvs: &'a Datastore) -> Executor<'a> { Executor { kvs, txn: None, diff --git a/lib/src/dbs/mod.rs b/lib/src/dbs/mod.rs index f6f3db60..acc1196f 100644 --- a/lib/src/dbs/mod.rs +++ b/lib/src/dbs/mod.rs @@ -1,5 +1,4 @@ mod auth; -mod dbs; mod executor; mod iterate; mod iterator; @@ -12,7 +11,6 @@ mod transaction; mod variables; pub use self::auth::*; -pub use self::dbs::*; pub use self::executor::*; pub use self::iterator::*; pub use self::options::*; diff --git a/lib/src/dbs/session.rs b/lib/src/dbs/session.rs index b4792505..c5ec28d8 100644 --- a/lib/src/dbs/session.rs +++ b/lib/src/dbs/session.rs @@ -1,11 +1,11 @@ use crate::ctx::Context; use crate::dbs::Auth; -use crate::dbs::Runtime; use crate::sql::value::Value; +use std::sync::Arc; #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Session { - pub au: Auth, // Authentication info + pub au: Arc, // Authentication info pub ip: Option, // Session ip address pub or: Option, // Session origin pub id: Option, // Session id @@ -16,8 +16,16 @@ pub struct Session { } impl Session { - pub fn context(&self) -> Runtime { - let mut ctx = Context::background(); + // Retrieves the selected namespace + pub fn ns(&self) -> Option> { + self.ns.to_owned().map(Arc::new) + } + // Retrieves the selected database + pub fn db(&self) -> Option> { + self.db.to_owned().map(Arc::new) + } + // Convert a session into a runtime + pub fn context(&self, mut ctx: Context) -> Context { // Add session value let key = String::from("session"); let val: Value = self.into(); @@ -31,7 +39,7 @@ impl Session { let val: Value = self.sd.to_owned().into(); ctx.add_value(key, val); // Output context - ctx.freeze() + ctx } } diff --git a/lib/src/dbs/test.rs b/lib/src/dbs/test.rs index 3b3ce2e6..7b4f89f8 100644 --- a/lib/src/dbs/test.rs +++ b/lib/src/dbs/test.rs @@ -2,12 +2,15 @@ use crate::ctx::Context; use crate::dbs::Options; use crate::dbs::Runtime; use crate::dbs::Transaction; +use crate::kvs::Datastore; use futures::lock::Mutex; use std::sync::Arc; pub async fn mock<'a>() -> (Runtime, Options, Transaction) { let ctx = Context::default().freeze(); let opt = Options::default(); - let txn = Arc::new(Mutex::new(crate::kvs::Transaction::Mock)); + let kvs = Datastore::new("memory").await.unwrap(); + let txn = kvs.transaction(true, false).await.unwrap(); + let txn = Arc::new(Mutex::new(txn)); (ctx, opt, txn) } diff --git a/lib/src/dbs/variables.rs b/lib/src/dbs/variables.rs index 7a6b863b..8a3b07ad 100644 --- a/lib/src/dbs/variables.rs +++ b/lib/src/dbs/variables.rs @@ -1,23 +1,21 @@ use crate::ctx::Context; use crate::sql::value::Value; use std::collections::HashMap; -use std::sync::Arc; pub type Variables = Option>; pub(crate) trait Attach { - fn attach(self, ctx: Arc) -> Arc; + fn attach(self, ctx: Context) -> Context; } impl Attach for Variables { - fn attach(self, ctx: Arc) -> Arc { + fn attach(self, mut ctx: Context) -> Context { match self { Some(m) => { - let mut ctx = Context::new(&ctx); for (key, val) in m { ctx.add_value(key, val); } - ctx.freeze() + ctx } None => ctx, } diff --git a/lib/src/kvs/ds.rs b/lib/src/kvs/ds.rs new file mode 100644 index 00000000..1c6c7e8f --- /dev/null +++ b/lib/src/kvs/ds.rs @@ -0,0 +1,186 @@ +use super::tx::Transaction; +use crate::ctx::Context; +use crate::dbs::Attach; +use crate::dbs::Executor; +use crate::dbs::Options; +use crate::dbs::Response; +use crate::dbs::Session; +use crate::dbs::Variables; +use crate::err::Error; +use crate::sql; +use crate::sql::query::Query; + +/// The underlying datastore instance which stores the dataset. +pub struct Datastore { + pub(super) inner: Inner, +} + +pub(super) enum Inner { + #[cfg(feature = "kv-echodb")] + Mem(super::mem::Datastore), + #[cfg(feature = "kv-indxdb")] + IxDB(super::ixdb::Datastore), + #[cfg(feature = "kv-yokudb")] + File(super::file::Datastore), + #[cfg(feature = "kv-tikv")] + TiKV(super::tikv::Datastore), +} + +impl Datastore { + /// Creates a new datastore instance + /// + /// # Examples + /// + /// ```rust,no_run + /// # use surrealdb::Datastore; + /// # fn main() -> Result<()> { + /// let ds = Datastore::new("memory")?; + /// # Ok(()) + /// # } + /// ``` + /// + /// Or to create a file-backed store: + /// + /// ```rust,no_run + /// # use surrealdb::Datastore; + /// # fn main() -> Result<()> { + /// let ds = Datastore::new("file://temp.db")?; + /// # Ok(()) + /// # } + /// ``` + /// + /// Or to connect to a tikv-backed distributed store: + /// + /// ```rust,no_run + /// # use surrealdb::Datastore; + /// # fn main() -> Result<()> { + /// let ds = Datastore::new("tikv://127.0.0.1:2379")?; + /// # Ok(()) + /// # } + /// ``` + pub async fn new(path: &str) -> Result { + match path { + #[cfg(feature = "kv-echodb")] + "memory" => { + info!("Starting kvs store in {}", path); + super::mem::Datastore::new().await.map(|v| Datastore { + inner: Inner::Mem(v), + }) + } + // Parse and initiate an IxDB database + #[cfg(feature = "kv-indxdb")] + s if s.starts_with("ixdb:") => { + info!("Starting kvs store at {}", path); + let s = s.trim_start_matches("ixdb://"); + super::ixdb::Datastore::new(s).await.map(|v| Datastore { + inner: Inner::IxDB(v), + }) + } + // Parse and initiate an File database + #[cfg(feature = "kv-yokudb")] + s if s.starts_with("file:") => { + info!("Starting kvs store at {}", path); + let s = s.trim_start_matches("file://"); + super::file::Datastore::new(s).await.map(|v| Datastore { + inner: Inner::File(v), + }) + } + // Parse and initiate an TiKV database + #[cfg(feature = "kv-tikv")] + s if s.starts_with("tikv:") => { + info!("Starting kvs store at {}", path); + let s = s.trim_start_matches("tikv://"); + super::tikv::Datastore::new(s).await.map(|v| Datastore { + inner: Inner::TiKV(v), + }) + } + // The datastore path is not valid + _ => unreachable!(), + } + } + /// Create a new transaction + pub async fn transaction(&self, write: bool, lock: bool) -> Result { + match &self.inner { + #[cfg(feature = "kv-echodb")] + Inner::Mem(v) => { + let tx = v.transaction(write, lock).await?; + Ok(Transaction { + inner: super::tx::Inner::Mem(tx), + }) + } + #[cfg(feature = "kv-indxdb")] + Inner::IxDB(v) => { + let tx = v.transaction(write, lock).await?; + Ok(Transaction { + inner: super::tx::Inner::IxDB(tx), + }) + } + #[cfg(feature = "kv-yokudb")] + Inner::File(v) => { + let tx = v.transaction(write, lock).await?; + Ok(Transaction { + inner: super::tx::Inner::File(tx), + }) + } + #[cfg(feature = "kv-tikv")] + Inner::TiKV(v) => { + let tx = v.transaction(write, lock).await?; + Ok(Transaction { + inner: super::tx::Inner::TiKV(tx), + }) + } + } + } + /// Execute a query + pub async fn execute( + &self, + txt: &str, + sess: &Session, + vars: Variables, + ) -> Result, Error> { + // Create a new query options + let mut opt = Options::default(); + // Create a new query executor + let mut exe = Executor::new(self); + // Create a default context + let ctx = Context::default(); + // Start an execution context + let ctx = sess.context(ctx); + // Store the query variables + let ctx = vars.attach(ctx); + // Parse the SQL query text + let ast = sql::parse(txt)?; + // Freeze the context + let ctx = ctx.freeze(); + // Process all statements + opt.auth = sess.au.clone(); + opt.ns = sess.ns(); + opt.db = sess.db(); + exe.execute(ctx, opt, ast).await + } + /// Execute a query + pub async fn process( + &self, + ast: Query, + sess: &Session, + vars: Variables, + ) -> Result, Error> { + // Create a new query options + let mut opt = Options::default(); + // Create a new query executor + let mut exe = Executor::new(self); + // Create a default context + let ctx = Context::default(); + // Start an execution context + let ctx = sess.context(ctx); + // Store the query variables + let ctx = vars.attach(ctx); + // Freeze the context + let ctx = ctx.freeze(); + // Process all statements + opt.auth = sess.au.clone(); + opt.ns = sess.ns(); + opt.db = sess.db(); + exe.execute(ctx, opt, ast).await + } +} diff --git a/lib/src/kvs/ex.rs b/lib/src/kvs/ex.rs deleted file mode 100644 index 51a1855c..00000000 --- a/lib/src/kvs/ex.rs +++ /dev/null @@ -1,285 +0,0 @@ -use super::Transaction; -use crate::err::Error; -use crate::kvs::Key; -use crate::kvs::Val; -use crate::sql; -use sql::statements::DefineDatabaseStatement; -use sql::statements::DefineEventStatement; -use sql::statements::DefineFieldStatement; -use sql::statements::DefineIndexStatement; -use sql::statements::DefineLoginStatement; -use sql::statements::DefineNamespaceStatement; -use sql::statements::DefineScopeStatement; -use sql::statements::DefineTableStatement; -use sql::statements::DefineTokenStatement; -use sql::statements::LiveStatement; - -pub trait Convert { - fn convert(self) -> T; -} - -impl Convert> for Vec<(Key, Val)> -where - T: From, -{ - fn convert(self) -> Vec { - self.into_iter().map(|(_, v)| v.into()).collect() - } -} - -impl Transaction { - // Get all namespaces - pub async fn all_ns(&mut self) -> Result, Error> { - let beg = crate::key::ns::prefix(); - let end = crate::key::ns::suffix(); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all namespace logins - pub async fn all_nl(&mut self, ns: &str) -> Result, Error> { - let beg = crate::key::nl::prefix(ns); - let end = crate::key::nl::suffix(ns); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all namespace tokens - pub async fn all_nt(&mut self, ns: &str) -> Result, Error> { - let beg = crate::key::nt::prefix(ns); - let end = crate::key::nt::suffix(ns); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all databases - pub async fn all_db(&mut self, ns: &str) -> Result, Error> { - let beg = crate::key::db::prefix(ns); - let end = crate::key::db::suffix(ns); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all database logins - pub async fn all_dl(&mut self, ns: &str, db: &str) -> Result, Error> { - let beg = crate::key::dl::prefix(ns, db); - let end = crate::key::dl::suffix(ns, db); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all database tokens - pub async fn all_dt(&mut self, ns: &str, db: &str) -> Result, Error> { - let beg = crate::key::dt::prefix(ns, db); - let end = crate::key::dt::suffix(ns, db); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all scopes - pub async fn all_sc(&mut self, ns: &str, db: &str) -> Result, Error> { - let beg = crate::key::sc::prefix(ns, db); - let end = crate::key::sc::suffix(ns, db); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all scope tokens - pub async fn all_st( - &mut self, - ns: &str, - db: &str, - sc: &str, - ) -> Result, Error> { - let beg = crate::key::st::prefix(ns, db, sc); - let end = crate::key::st::suffix(ns, db, sc); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all tables - pub async fn all_tb(&mut self, ns: &str, db: &str) -> Result, Error> { - let beg = crate::key::tb::prefix(ns, db); - let end = crate::key::tb::suffix(ns, db); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all events - pub async fn all_ev( - &mut self, - ns: &str, - db: &str, - tb: &str, - ) -> Result, Error> { - let beg = crate::key::ev::prefix(ns, db, tb); - let end = crate::key::ev::suffix(ns, db, tb); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all fields - pub async fn all_fd( - &mut self, - ns: &str, - db: &str, - tb: &str, - ) -> Result, Error> { - let beg = crate::key::fd::prefix(ns, db, tb); - let end = crate::key::fd::suffix(ns, db, tb); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all fields - pub async fn all_ix( - &mut self, - ns: &str, - db: &str, - tb: &str, - ) -> Result, Error> { - let beg = crate::key::ix::prefix(ns, db, tb); - let end = crate::key::ix::suffix(ns, db, tb); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all views - pub async fn all_ft( - &mut self, - ns: &str, - db: &str, - tb: &str, - ) -> Result, Error> { - let beg = crate::key::ft::prefix(ns, db, tb); - let end = crate::key::ft::suffix(ns, db, tb); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } - // Get all lives - pub async fn all_lv( - &mut self, - ns: &str, - db: &str, - tb: &str, - ) -> Result, Error> { - let beg = crate::key::lv::prefix(ns, db, tb); - let end = crate::key::lv::suffix(ns, db, tb); - let val = self.getr(beg..end, u32::MAX).await?; - Ok(val.convert()) - } -} - -impl Transaction { - // Get a namespace - pub async fn get_ns(&mut self, ns: &str) -> Result { - let key = crate::key::ns::new(ns); - let val = self.get(key).await?.ok_or(Error::NsNotFound)?; - Ok(val.into()) - } - // Get a namespace login - pub async fn get_nl(&mut self, ns: &str, nl: &str) -> Result { - let key = crate::key::nl::new(ns, nl); - let val = self.get(key).await?.ok_or(Error::NlNotFound)?; - Ok(val.into()) - } - // Get a namespace token - pub async fn get_nt(&mut self, ns: &str, nt: &str) -> Result { - let key = crate::key::nt::new(ns, nt); - let val = self.get(key).await?.ok_or(Error::NtNotFound)?; - Ok(val.into()) - } - // Get a database - pub async fn get_db(&mut self, ns: &str, db: &str) -> Result { - let key = crate::key::db::new(ns, db); - let val = self.get(key).await?.ok_or(Error::DbNotFound)?; - Ok(val.into()) - } - // Get a database login - pub async fn get_dl( - &mut self, - ns: &str, - db: &str, - dl: &str, - ) -> Result { - let key = crate::key::dl::new(ns, db, dl); - let val = self.get(key).await?.ok_or(Error::DlNotFound)?; - Ok(val.into()) - } - // Get a database token - pub async fn get_dt( - &mut self, - ns: &str, - db: &str, - dt: &str, - ) -> Result { - let key = crate::key::dt::new(ns, db, dt); - let val = self.get(key).await?.ok_or(Error::DtNotFound)?; - Ok(val.into()) - } - // Get a scope - pub async fn get_sc( - &mut self, - ns: &str, - db: &str, - sc: &str, - ) -> Result { - let key = crate::key::sc::new(ns, db, sc); - let val = self.get(key).await?.ok_or(Error::ScNotFound)?; - Ok(val.into()) - } - // Get a scope token - pub async fn get_st( - &mut self, - ns: &str, - db: &str, - sc: &str, - st: &str, - ) -> Result { - let key = crate::key::st::new(ns, db, sc, st); - let val = self.get(key).await?.ok_or(Error::StNotFound)?; - Ok(val.into()) - } - // Get a table - pub async fn get_tb( - &mut self, - ns: &str, - db: &str, - tb: &str, - ) -> Result { - let key = crate::key::tb::new(ns, db, tb); - let val = self.get(key).await?.ok_or(Error::TbNotFound)?; - Ok(val.into()) - } -} - -impl Transaction { - // Get all namespaces - pub async fn add_ns(&mut self, ns: &str) -> Result<(), Error> { - let key = crate::key::ns::new(ns); - let _ = self - .put( - key, - DefineNamespaceStatement { - name: ns.to_owned(), - }, - ) - .await; - Ok(()) - } - // Get all namespace logins - pub async fn add_db(&mut self, ns: &str, db: &str) -> Result<(), Error> { - let key = crate::key::db::new(ns, db); - let _ = self - .put( - key, - DefineDatabaseStatement { - name: db.to_owned(), - }, - ) - .await; - Ok(()) - } - // Get all namespace tokens - pub async fn add_tb(&mut self, ns: &str, db: &str, tb: &str) -> Result<(), Error> { - let key = crate::key::tb::new(ns, db, tb); - let _ = self - .put( - key, - DefineTableStatement { - name: tb.to_owned(), - ..DefineTableStatement::default() - }, - ) - .await; - Ok(()) - } -} diff --git a/lib/src/kvs/kv.rs b/lib/src/kvs/kv.rs index a17b4a69..a27271d3 100644 --- a/lib/src/kvs/kv.rs +++ b/lib/src/kvs/kv.rs @@ -1,3 +1,31 @@ +/// The key part of a key-value pair. An alias for [`Vec`]. pub type Key = Vec; +/// The value part of a key-value pair. An alias for [`Vec`]. pub type Val = Vec; + +// This trait appends an element to a collection, and allows chaining +pub(super) trait Add { + fn add(self, v: T) -> Self; +} + +impl Add for Vec { + fn add(mut self, v: u8) -> Self { + self.push(v); + self + } +} + +// This trait converts a collection of key-value pairs into the desired type +pub(super) trait Convert { + fn convert(self) -> T; +} + +impl Convert> for Vec<(Key, Val)> +where + T: From, +{ + fn convert(self) -> Vec { + self.into_iter().map(|(_, v)| v.into()).collect() + } +} diff --git a/lib/src/kvs/mod.rs b/lib/src/kvs/mod.rs index 9feed3e0..77e2957d 100644 --- a/lib/src/kvs/mod.rs +++ b/lib/src/kvs/mod.rs @@ -1,4 +1,4 @@ -mod ex; +mod ds; mod file; mod ixdb; mod kv; @@ -6,99 +6,6 @@ mod mem; mod tikv; mod tx; +pub use self::ds::*; pub use self::kv::*; pub use self::tx::*; - -use crate::err::Error; -use std::sync::Arc; - -pub type Store = Arc; - -pub enum Datastore { - Mock, - #[cfg(feature = "kv-echodb")] - Mem(mem::Datastore), - #[cfg(feature = "kv-indxdb")] - IxDB(ixdb::Datastore), - #[cfg(feature = "kv-yokudb")] - File(file::Datastore), - #[cfg(feature = "kv-tikv")] - TiKV(tikv::Datastore), -} - -pub enum Transaction { - Mock, - #[cfg(feature = "kv-echodb")] - Mem(mem::Transaction), - #[cfg(feature = "kv-indxdb")] - IxDB(ixdb::Transaction), - #[cfg(feature = "kv-yokudb")] - File(file::Transaction), - #[cfg(feature = "kv-tikv")] - TiKV(tikv::Transaction), -} - -impl Datastore { - // Create a new datastore - pub async fn new(path: &str) -> Result { - match path { - #[cfg(feature = "kv-echodb")] - "memory" => { - info!("Starting kvs store in {}", path); - mem::Datastore::new().await.map(Datastore::Mem) - } - // Parse and initiate an IxDB database - #[cfg(feature = "kv-indxdb")] - s if s.starts_with("ixdb:") => { - info!("Starting kvs store at {}", path); - let s = s.trim_start_matches("ixdb://"); - ixdb::Datastore::new(s).await.map(Datastore::IxDB) - } - // Parse and initiate an File database - #[cfg(feature = "kv-yokudb")] - s if s.starts_with("file:") => { - info!("Starting kvs store at {}", path); - let s = s.trim_start_matches("file://"); - file::Datastore::new(s).await.map(Datastore::File) - } - // Parse and initiate an TiKV database - #[cfg(feature = "kv-tikv")] - s if s.starts_with("tikv:") => { - info!("Starting kvs store at {}", path); - let s = s.trim_start_matches("tikv://"); - tikv::Datastore::new(s).await.map(Datastore::TiKV) - } - // The datastore path is not valid - _ => unreachable!(), - } - } - // Create a new transaction - pub async fn transaction(&self, write: bool, lock: bool) -> Result { - match self { - Datastore::Mock => { - let tx = Transaction::Mock; - Ok(tx) - } - #[cfg(feature = "kv-echodb")] - Datastore::Mem(v) => { - let tx = v.transaction(write, lock).await?; - Ok(Transaction::Mem(tx)) - } - #[cfg(feature = "kv-indxdb")] - Datastore::IxDB(v) => { - let tx = v.transaction(write, lock).await?; - Ok(Transaction::IxDB(tx)) - } - #[cfg(feature = "kv-yokudb")] - Datastore::File(v) => { - let tx = v.transaction(write, lock).await?; - Ok(Transaction::File(tx)) - } - #[cfg(feature = "kv-tikv")] - Datastore::TiKV(v) => { - let tx = v.transaction(write, lock).await?; - Ok(Transaction::TiKV(tx)) - } - } - } -} diff --git a/lib/src/kvs/tx.rs b/lib/src/kvs/tx.rs index 485c447f..e1de620c 100644 --- a/lib/src/kvs/tx.rs +++ b/lib/src/kvs/tx.rs @@ -1,204 +1,311 @@ -use super::Transaction; +use super::kv::Add; +use super::kv::Convert; +use super::Key; +use super::Val; use crate::err::Error; -use crate::kvs::Key; -use crate::kvs::Val; +use crate::sql; +use sql::statements::DefineDatabaseStatement; +use sql::statements::DefineEventStatement; +use sql::statements::DefineFieldStatement; +use sql::statements::DefineIndexStatement; +use sql::statements::DefineLoginStatement; +use sql::statements::DefineNamespaceStatement; +use sql::statements::DefineScopeStatement; +use sql::statements::DefineTableStatement; +use sql::statements::DefineTokenStatement; +use sql::statements::LiveStatement; use std::ops::Range; -trait Add { - fn add(self, v: T) -> Self; +/// A set of undoable updates and requests against a dataset. +pub struct Transaction { + pub(super) inner: Inner, } -impl Add for Vec { - fn add(mut self, v: u8) -> Self { - self.push(v); - self - } +pub(super) enum Inner { + #[cfg(feature = "kv-echodb")] + Mem(super::mem::Transaction), + #[cfg(feature = "kv-indxdb")] + IxDB(super::ixdb::Transaction), + #[cfg(feature = "kv-yokudb")] + File(super::file::Transaction), + #[cfg(feature = "kv-tikv")] + TiKV(super::tikv::Transaction), } impl Transaction { - // Check if closed + /// Check if transactions is finished. + /// + /// If the transaction has been cancelled or committed, + /// then this function will return [`true`], and any further + /// calls to functions on this transaction will result + /// in a [`Error::TxFinished`] error. pub async fn closed(&self) -> bool { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.closed(), + Transaction { + inner: Inner::Mem(v), + } => v.closed(), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.closed(), + Transaction { + inner: Inner::File(v), + } => v.closed(), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.closed(), + Transaction { + inner: Inner::IxDB(v), + } => v.closed(), #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.closed(), + Transaction { + inner: Inner::TiKV(v), + } => v.closed(), } } - // Cancel a transaction + /// Cancel a transaction. + /// + /// This reverses all changes made within the transaction. pub async fn cancel(&mut self) -> Result<(), Error> { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.cancel(), + Transaction { + inner: Inner::Mem(v), + } => v.cancel(), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.cancel(), + Transaction { + inner: Inner::File(v), + } => v.cancel(), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.cancel().await, + Transaction { + inner: Inner::IxDB(v), + } => v.cancel().await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.cancel().await, + Transaction { + inner: Inner::TiKV(v), + } => v.cancel().await, } } - // Commit a transaction + /// Commit a transaction. + /// + /// This attempts to commit all changes made within the transaction. pub async fn commit(&mut self) -> Result<(), Error> { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.commit(), + Transaction { + inner: Inner::Mem(v), + } => v.commit(), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.commit(), + Transaction { + inner: Inner::File(v), + } => v.commit(), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.commit().await, + Transaction { + inner: Inner::IxDB(v), + } => v.commit().await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.commit().await, + Transaction { + inner: Inner::TiKV(v), + } => v.commit().await, } } - // Delete a key + /// Delete a key from the datastore. pub async fn del(&mut self, key: K) -> Result<(), Error> where K: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.del(key), + Transaction { + inner: Inner::Mem(v), + } => v.del(key), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.del(key), + Transaction { + inner: Inner::File(v), + } => v.del(key), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.del(key).await, + Transaction { + inner: Inner::IxDB(v), + } => v.del(key).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.del(key).await, + Transaction { + inner: Inner::TiKV(v), + } => v.del(key).await, } } - // Check if a key exists + /// Check if a key exists in the datastore. pub async fn exi(&mut self, key: K) -> Result where K: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.exi(key), + Transaction { + inner: Inner::Mem(v), + } => v.exi(key), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.exi(key), + Transaction { + inner: Inner::File(v), + } => v.exi(key), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.exi(key).await, + Transaction { + inner: Inner::IxDB(v), + } => v.exi(key).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.exi(key).await, + Transaction { + inner: Inner::TiKV(v), + } => v.exi(key).await, } } - // Fetch a key from the database + /// Fetch a key from the datastore. pub async fn get(&mut self, key: K) -> Result, Error> where K: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.get(key), + Transaction { + inner: Inner::Mem(v), + } => v.get(key), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.get(key), + Transaction { + inner: Inner::File(v), + } => v.get(key), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.get(key).await, + Transaction { + inner: Inner::IxDB(v), + } => v.get(key).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.get(key).await, + Transaction { + inner: Inner::TiKV(v), + } => v.get(key).await, } } - // Insert or update a key in the database + /// Insert or update a key in the datastore. pub async fn set(&mut self, key: K, val: V) -> Result<(), Error> where K: Into, V: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.set(key, val), + Transaction { + inner: Inner::Mem(v), + } => v.set(key, val), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.set(key, val), + Transaction { + inner: Inner::File(v), + } => v.set(key, val), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.set(key, val).await, + Transaction { + inner: Inner::IxDB(v), + } => v.set(key, val).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.set(key, val).await, + Transaction { + inner: Inner::TiKV(v), + } => v.set(key, val).await, } } - // Insert a key if it doesn't exist in the database + /// Insert a key if it doesn't exist in the datastore. pub async fn put(&mut self, key: K, val: V) -> Result<(), Error> where K: Into, V: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.put(key, val), + Transaction { + inner: Inner::Mem(v), + } => v.put(key, val), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.put(key, val), + Transaction { + inner: Inner::File(v), + } => v.put(key, val), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.put(key, val).await, + Transaction { + inner: Inner::IxDB(v), + } => v.put(key, val).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.put(key, val).await, + Transaction { + inner: Inner::TiKV(v), + } => v.put(key, val).await, } } - // Retrieve a range of keys from the databases + /// Retrieve a specific range of keys from the datastore. + /// + /// This function fetches the full range of key-value pairs, in a single request to the underlying datastore. pub async fn scan(&mut self, rng: Range, limit: u32) -> Result, Error> where K: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.scan(rng, limit), + Transaction { + inner: Inner::Mem(v), + } => v.scan(rng, limit), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.scan(rng, limit), + Transaction { + inner: Inner::File(v), + } => v.scan(rng, limit), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.scan(rng, limit).await, + Transaction { + inner: Inner::IxDB(v), + } => v.scan(rng, limit).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.scan(rng, limit).await, + Transaction { + inner: Inner::TiKV(v), + } => v.scan(rng, limit).await, } } - // Delete a range of keys from the databases + /// Update a key in the datastore if the current value matches a condition. pub async fn putc(&mut self, key: K, val: V, chk: Option) -> Result<(), Error> where K: Into, V: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.putc(key, val, chk), + Transaction { + inner: Inner::Mem(v), + } => v.putc(key, val, chk), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.putc(key, val, chk), + Transaction { + inner: Inner::File(v), + } => v.putc(key, val, chk), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.putc(key, val, chk).await, + Transaction { + inner: Inner::IxDB(v), + } => v.putc(key, val, chk).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.putc(key, val, chk).await, + Transaction { + inner: Inner::TiKV(v), + } => v.putc(key, val, chk).await, } } - // Delete a range of keys from the databases + /// Delete a key from the datastore if the current value matches a condition. pub async fn delc(&mut self, key: K, chk: Option) -> Result<(), Error> where K: Into, V: Into, { match self { - Transaction::Mock => unreachable!(), #[cfg(feature = "kv-echodb")] - Transaction::Mem(v) => v.delc(key, chk), + Transaction { + inner: Inner::Mem(v), + } => v.delc(key, chk), #[cfg(feature = "kv-yokudb")] - Transaction::File(v) => v.delc(key, chk), + Transaction { + inner: Inner::File(v), + } => v.delc(key, chk), #[cfg(feature = "kv-indxdb")] - Transaction::IxDB(v) => v.delc(key, chk).await, + Transaction { + inner: Inner::IxDB(v), + } => v.delc(key, chk).await, #[cfg(feature = "kv-tikv")] - Transaction::TiKV(v) => v.delc(key, chk).await, + Transaction { + inner: Inner::TiKV(v), + } => v.delc(key, chk).await, } } - // Retrieve a range of keys from the databases + /// Retrieve a specific range of keys from the datastore. + /// + /// This function fetches key-value pairs from the underlying datastore in batches of 1000. pub async fn getr(&mut self, rng: Range, limit: u32) -> Result, Error> where K: Into, @@ -246,7 +353,9 @@ impl Transaction { } Ok(out) } - // Delete a range of keys from the databases + /// Delete a range of keys from the datastore. + /// + /// This function fetches key-value pairs from the underlying datastore in batches of 1000. pub async fn delr(&mut self, rng: Range, limit: u32) -> Result<(), Error> where K: Into, @@ -293,7 +402,9 @@ impl Transaction { } Ok(()) } - // Retrieve a prefix of keys from the databases + /// Retrieve a specific prefix of keys from the datastore. + /// + /// This function fetches key-value pairs from the underlying datastore in batches of 1000. pub async fn getp(&mut self, key: K, limit: u32) -> Result, Error> where K: Into, @@ -341,7 +452,9 @@ impl Transaction { } Ok(out) } - // Delete a prefix of keys from the databases + /// Delete a prefix of keys from the datastore. + /// + /// This function fetches key-value pairs from the underlying datastore in batches of 1000. pub async fn delp(&mut self, key: K, limit: u32) -> Result<(), Error> where K: Into, @@ -388,4 +501,252 @@ impl Transaction { } Ok(()) } + /// Retrieve all namespace definitions in a datastore. + pub async fn all_ns(&mut self) -> Result, Error> { + let beg = crate::key::ns::prefix(); + let end = crate::key::ns::suffix(); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all namespace login definitions for a specific namespace. + pub async fn all_nl(&mut self, ns: &str) -> Result, Error> { + let beg = crate::key::nl::prefix(ns); + let end = crate::key::nl::suffix(ns); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all namespace token definitions for a specific namespace. + pub async fn all_nt(&mut self, ns: &str) -> Result, Error> { + let beg = crate::key::nt::prefix(ns); + let end = crate::key::nt::suffix(ns); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all database definitions for a specific namespace. + pub async fn all_db(&mut self, ns: &str) -> Result, Error> { + let beg = crate::key::db::prefix(ns); + let end = crate::key::db::suffix(ns); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all database login definitions for a specific database. + pub async fn all_dl(&mut self, ns: &str, db: &str) -> Result, Error> { + let beg = crate::key::dl::prefix(ns, db); + let end = crate::key::dl::suffix(ns, db); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all database token definitions for a specific database. + pub async fn all_dt(&mut self, ns: &str, db: &str) -> Result, Error> { + let beg = crate::key::dt::prefix(ns, db); + let end = crate::key::dt::suffix(ns, db); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all scope definitions for a specific database. + pub async fn all_sc(&mut self, ns: &str, db: &str) -> Result, Error> { + let beg = crate::key::sc::prefix(ns, db); + let end = crate::key::sc::suffix(ns, db); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all scope token definitions for a scope. + pub async fn all_st( + &mut self, + ns: &str, + db: &str, + sc: &str, + ) -> Result, Error> { + let beg = crate::key::st::prefix(ns, db, sc); + let end = crate::key::st::suffix(ns, db, sc); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all table definitions for a specific database. + pub async fn all_tb(&mut self, ns: &str, db: &str) -> Result, Error> { + let beg = crate::key::tb::prefix(ns, db); + let end = crate::key::tb::suffix(ns, db); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all event definitions for a specific table. + pub async fn all_ev( + &mut self, + ns: &str, + db: &str, + tb: &str, + ) -> Result, Error> { + let beg = crate::key::ev::prefix(ns, db, tb); + let end = crate::key::ev::suffix(ns, db, tb); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all field definitions for a specific table. + pub async fn all_fd( + &mut self, + ns: &str, + db: &str, + tb: &str, + ) -> Result, Error> { + let beg = crate::key::fd::prefix(ns, db, tb); + let end = crate::key::fd::suffix(ns, db, tb); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all index definitions for a specific table. + pub async fn all_ix( + &mut self, + ns: &str, + db: &str, + tb: &str, + ) -> Result, Error> { + let beg = crate::key::ix::prefix(ns, db, tb); + let end = crate::key::ix::suffix(ns, db, tb); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all view definitions for a specific table. + pub async fn all_ft( + &mut self, + ns: &str, + db: &str, + tb: &str, + ) -> Result, Error> { + let beg = crate::key::ft::prefix(ns, db, tb); + let end = crate::key::ft::suffix(ns, db, tb); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve all live definitions for a specific table. + pub async fn all_lv( + &mut self, + ns: &str, + db: &str, + tb: &str, + ) -> Result, Error> { + let beg = crate::key::lv::prefix(ns, db, tb); + let end = crate::key::lv::suffix(ns, db, tb); + let val = self.getr(beg..end, u32::MAX).await?; + Ok(val.convert()) + } + /// Retrieve a specific namespace definition. + pub async fn get_ns(&mut self, ns: &str) -> Result { + let key = crate::key::ns::new(ns); + let val = self.get(key).await?.ok_or(Error::NsNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific namespace login definition. + pub async fn get_nl(&mut self, ns: &str, nl: &str) -> Result { + let key = crate::key::nl::new(ns, nl); + let val = self.get(key).await?.ok_or(Error::NlNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific namespace token definition. + pub async fn get_nt(&mut self, ns: &str, nt: &str) -> Result { + let key = crate::key::nt::new(ns, nt); + let val = self.get(key).await?.ok_or(Error::NtNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific database definition. + pub async fn get_db(&mut self, ns: &str, db: &str) -> Result { + let key = crate::key::db::new(ns, db); + let val = self.get(key).await?.ok_or(Error::DbNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific database login definition. + pub async fn get_dl( + &mut self, + ns: &str, + db: &str, + dl: &str, + ) -> Result { + let key = crate::key::dl::new(ns, db, dl); + let val = self.get(key).await?.ok_or(Error::DlNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific database token definition. + pub async fn get_dt( + &mut self, + ns: &str, + db: &str, + dt: &str, + ) -> Result { + let key = crate::key::dt::new(ns, db, dt); + let val = self.get(key).await?.ok_or(Error::DtNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific scope definition. + pub async fn get_sc( + &mut self, + ns: &str, + db: &str, + sc: &str, + ) -> Result { + let key = crate::key::sc::new(ns, db, sc); + let val = self.get(key).await?.ok_or(Error::ScNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific scope token definition. + pub async fn get_st( + &mut self, + ns: &str, + db: &str, + sc: &str, + st: &str, + ) -> Result { + let key = crate::key::st::new(ns, db, sc, st); + let val = self.get(key).await?.ok_or(Error::StNotFound)?; + Ok(val.into()) + } + /// Retrieve a specific table definition. + pub async fn get_tb( + &mut self, + ns: &str, + db: &str, + tb: &str, + ) -> Result { + let key = crate::key::tb::new(ns, db, tb); + let val = self.get(key).await?.ok_or(Error::TbNotFound)?; + Ok(val.into()) + } + /// Add a namespace with a default configuration. + pub async fn add_ns(&mut self, ns: &str) -> Result<(), Error> { + let key = crate::key::ns::new(ns); + let _ = self + .put( + key, + DefineNamespaceStatement { + name: ns.to_owned(), + }, + ) + .await; + Ok(()) + } + /// Add a database with a default configuration. + pub async fn add_db(&mut self, ns: &str, db: &str) -> Result<(), Error> { + let key = crate::key::db::new(ns, db); + let _ = self + .put( + key, + DefineDatabaseStatement { + name: db.to_owned(), + }, + ) + .await; + Ok(()) + } + /// Add a table with a default configuration. + pub async fn add_tb(&mut self, ns: &str, db: &str, tb: &str) -> Result<(), Error> { + let key = crate::key::tb::new(ns, db, tb); + let _ = self + .put( + key, + DefineTableStatement { + name: tb.to_owned(), + ..DefineTableStatement::default() + }, + ) + .await; + Ok(()) + } } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 9c51a847..630ef4a0 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -19,8 +19,6 @@ pub mod sql; pub use err::Error; -pub use dbs::execute; -pub use dbs::process; pub use dbs::Auth; pub use dbs::Response; pub use dbs::Session; diff --git a/src/net/conf.rs b/src/net/conf.rs index 8426c44f..488170d5 100644 --- a/src/net/conf.rs +++ b/src/net/conf.rs @@ -1,4 +1,5 @@ use std::net::SocketAddr; +use std::sync::Arc; use surrealdb::Auth; use surrealdb::Session; use warp::Filter; @@ -32,7 +33,7 @@ fn process( ) -> Session { // Create session let conf = Session { - au: Auth::default(), + au: Arc::new(Auth::default()), ip: ip.map(|v| v.to_string()), or, id, diff --git a/src/net/key.rs b/src/net/key.rs index 2762361d..305531ef 100644 --- a/src/net/key.rs +++ b/src/net/key.rs @@ -106,7 +106,7 @@ async fn select_all( table: String, query: Query, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let sql = format!( "SELECT * FROM type::table($table) LIMIT {l} START {s}", l = query.limit.unwrap_or_else(|| String::from("100")), @@ -115,7 +115,7 @@ async fn select_all( let vars = map! { String::from("table") => Value::from(table), }; - match surrealdb::execute(db, sql.as_str(), session, Some(vars)).await { + match db.execute(sql.as_str(), &session, Some(vars)).await { Ok(ref res) => match output.as_ref() { "application/json" => Ok(output::json(res)), "application/cbor" => Ok(output::cbor(res)), @@ -132,7 +132,7 @@ async fn create_all( table: String, body: Bytes, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let data = str::from_utf8(&body).unwrap(); match surrealdb::sql::json(data) { Ok(data) => { @@ -141,7 +141,7 @@ async fn create_all( String::from("table") => Value::from(table), String::from("data") => data, }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), @@ -160,12 +160,12 @@ async fn delete_all( output: String, table: String, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let sql = "DELETE type::table($table)"; let vars = map! { String::from("table") => Value::from(table), }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), @@ -186,13 +186,13 @@ async fn select_one( table: String, id: String, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let sql = "SELECT * FROM type::thing($table, $id)"; let vars = map! { String::from("table") => Value::from(table), String::from("id") => Value::from(id), }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), @@ -210,7 +210,7 @@ async fn create_one( id: String, body: Bytes, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let data = str::from_utf8(&body).unwrap(); match surrealdb::sql::json(data) { Ok(data) => { @@ -220,7 +220,7 @@ async fn create_one( String::from("id") => Value::from(id), String::from("data") => data, }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), @@ -241,7 +241,7 @@ async fn update_one( id: String, body: Bytes, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let data = str::from_utf8(&body).unwrap(); match surrealdb::sql::json(data) { Ok(data) => { @@ -251,7 +251,7 @@ async fn update_one( String::from("id") => Value::from(id), String::from("data") => data, }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), @@ -272,7 +272,7 @@ async fn modify_one( id: String, body: Bytes, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let data = str::from_utf8(&body).unwrap(); match surrealdb::sql::json(data) { Ok(data) => { @@ -282,7 +282,7 @@ async fn modify_one( String::from("id") => Value::from(id), String::from("data") => data, }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), @@ -302,13 +302,13 @@ async fn delete_one( table: String, id: String, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let sql = "DELETE type::thing($table, $id)"; let vars = map! { String::from("table") => Value::from(table), String::from("id") => Value::from(id), }; - match surrealdb::execute(db, sql, session, Some(vars)).await { + match db.execute(sql, &session, Some(vars)).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)), diff --git a/src/net/sql.rs b/src/net/sql.rs index 26b83712..711feaaa 100644 --- a/src/net/sql.rs +++ b/src/net/sql.rs @@ -42,9 +42,9 @@ async fn handler( output: String, sql: Bytes, ) -> Result { - let db = DB.get().unwrap().clone(); + let db = DB.get().unwrap(); let sql = std::str::from_utf8(&sql).unwrap(); - match surrealdb::execute(db, sql, session, None).await { + match db.execute(sql, &session, None).await { Ok(res) => match output.as_ref() { "application/json" => Ok(output::json(&res)), "application/cbor" => Ok(output::cbor(&res)),