Only pass transaction when processing queries

Instead of passing the executor instance, we only need to pass the current transaction which is to be used for processing and running any queries.
This commit is contained in:
Tobie Morgan Hitchcock 2022-02-15 01:00:30 +00:00
parent acc466c360
commit efa67bb043
65 changed files with 541 additions and 507 deletions

View file

@ -26,6 +26,13 @@ impl<'a> Executor<'a> {
}
}
fn txn(&self) -> Arc<Mutex<Transaction<'a>>> {
match &self.txn {
Some(txn) => txn.clone(),
None => unreachable!(),
}
}
async fn begin(&mut self) -> bool {
match &self.txn {
Some(_) => false,
@ -198,7 +205,7 @@ impl<'a> Executor<'a> {
}
// Process param definition statements
Statement::Set(stm) => {
match stm.compute(&ctx, &opt, self, None).await {
match stm.compute(&ctx, &opt, &self.txn(), None).await {
Ok(val) => {
let mut new = Context::new(&ctx);
let key = stm.name.to_owned();
@ -226,7 +233,7 @@ impl<'a> Executor<'a> {
ctx = new.freeze();
}
// Process the statement
let res = stm.compute(&ctx, &opt, self, None).await;
let res = stm.compute(&ctx, &opt, &self.txn(), None).await;
// Catch statement timeout
let res = match stm.timeout() {
Some(timeout) => match ctx.is_timedout() {

View file

@ -1,8 +1,8 @@
use crate::cnf::ID_CHARS;
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::array::Array;
use crate::sql::model::Model;
@ -18,15 +18,15 @@ impl Value {
self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
ite: &mut Iterator<'_>,
) -> Result<(), Error> {
match self {
Value::Array(v) => v.iterate(ctx, opt, exe, ite).await?,
Value::Model(v) => v.iterate(ctx, opt, exe, ite).await?,
Value::Thing(v) => v.iterate(ctx, opt, exe, ite).await?,
Value::Table(v) => v.iterate(ctx, opt, exe, ite).await?,
v => ite.process(ctx, opt, exe, None, v).await,
Value::Array(v) => v.iterate(ctx, opt, txn, ite).await?,
Value::Model(v) => v.iterate(ctx, opt, txn, ite).await?,
Value::Thing(v) => v.iterate(ctx, opt, txn, ite).await?,
Value::Table(v) => v.iterate(ctx, opt, txn, ite).await?,
v => ite.process(ctx, opt, txn, None, v).await,
}
Ok(())
}
@ -38,16 +38,16 @@ impl Array {
self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
ite: &mut Iterator<'_>,
) -> Result<(), Error> {
for v in self.value.into_iter() {
match v {
Value::Array(v) => v.iterate(ctx, opt, exe, ite).await?,
Value::Model(v) => v.iterate(ctx, opt, exe, ite).await?,
Value::Thing(v) => v.iterate(ctx, opt, exe, ite).await?,
Value::Table(v) => v.iterate(ctx, opt, exe, ite).await?,
v => ite.process(ctx, opt, exe, None, v).await,
Value::Array(v) => v.iterate(ctx, opt, txn, ite).await?,
Value::Model(v) => v.iterate(ctx, opt, txn, ite).await?,
Value::Thing(v) => v.iterate(ctx, opt, txn, ite).await?,
Value::Table(v) => v.iterate(ctx, opt, txn, ite).await?,
v => ite.process(ctx, opt, txn, None, v).await,
}
}
Ok(())
@ -59,7 +59,7 @@ impl Model {
self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
ite: &mut Iterator<'_>,
) -> Result<(), Error> {
if ctx.is_ok() {
@ -69,7 +69,7 @@ impl Model {
tb: self.table.to_string(),
id: nanoid!(20, &ID_CHARS),
}
.iterate(ctx, opt, exe, ite)
.iterate(ctx, opt, txn, ite)
.await?;
}
}
@ -79,7 +79,7 @@ impl Model {
tb: self.table.to_string(),
id: x.to_string(),
}
.iterate(ctx, opt, exe, ite)
.iterate(ctx, opt, txn, ite)
.await?;
}
}
@ -93,10 +93,10 @@ impl Thing {
self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
ite: &mut Iterator<'_>,
) -> Result<(), Error> {
todo!()
Ok(())
}
}
@ -105,9 +105,9 @@ impl Table {
self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
ite: &mut Iterator<'_>,
) -> Result<(), Error> {
todo!()
Ok(())
}
}

View file

@ -1,10 +1,10 @@
use crate::cnf::ID_CHARS;
use crate::ctx::Canceller;
use crate::ctx::Context;
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::group::Groups;
@ -69,7 +69,7 @@ impl<'a> Iterator<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
) -> Result<Value, Error> {
// Log the statement
trace!("Iterating {}", self.stmt);
@ -78,55 +78,55 @@ impl<'a> Iterator<'a> {
self.run = ctx.add_cancel();
let ctx = ctx.freeze();
// Process prepared values
self.iterate(&ctx, opt, exe).await?;
self.iterate(&ctx, opt, txn).await?;
// Return any document errors
if let Some(e) = self.error.take() {
return Err(e);
}
// Process any SPLIT clause
self.output_split(&ctx, opt, exe);
self.output_split(&ctx, opt, txn);
// Process any GROUP clause
self.output_group(&ctx, opt, exe);
self.output_group(&ctx, opt, txn);
// Process any ORDER clause
self.output_order(&ctx, opt, exe);
self.output_order(&ctx, opt, txn);
// Process any START clause
self.output_start(&ctx, opt, exe);
self.output_start(&ctx, opt, txn);
// Process any LIMIT clause
self.output_limit(&ctx, opt, exe);
self.output_limit(&ctx, opt, txn);
// Output the results
Ok(mem::take(&mut self.results).into())
}
#[inline]
fn output_split(&mut self, ctx: &Runtime, opt: &Options, exe: &Executor) {
fn output_split(&mut self, ctx: &Runtime, opt: &Options, txn: &Transaction) {
if self.split.is_some() {
// Ignore
}
}
#[inline]
fn output_group(&mut self, ctx: &Runtime, opt: &Options, exe: &Executor) {
fn output_group(&mut self, ctx: &Runtime, opt: &Options, txn: &Transaction) {
if self.group.is_some() {
// Ignore
}
}
#[inline]
fn output_order(&mut self, ctx: &Runtime, opt: &Options, exe: &Executor) {
fn output_order(&mut self, ctx: &Runtime, opt: &Options, txn: &Transaction) {
if self.order.is_some() {
// Ignore
}
}
#[inline]
fn output_start(&mut self, ctx: &Runtime, opt: &Options, exe: &Executor) {
fn output_start(&mut self, ctx: &Runtime, opt: &Options, txn: &Transaction) {
if let Some(v) = self.start {
self.results = mem::take(&mut self.results).into_iter().skip(v.0).collect();
}
}
#[inline]
fn output_limit(&mut self, ctx: &Runtime, opt: &Options, exe: &Executor) {
fn output_limit(&mut self, ctx: &Runtime, opt: &Options, txn: &Transaction) {
if let Some(v) = self.limit {
self.results = mem::take(&mut self.results).into_iter().take(v.0).collect();
}
@ -136,7 +136,7 @@ impl<'a> Iterator<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
) -> Result<(), Error> {
match self.parallel {
// Run statements in parallel
@ -149,7 +149,7 @@ impl<'a> Iterator<'a> {
}
// Process all processed values
while let Some(v) = rx.recv().await {
self.process(&ctx, opt, exe, None, v).await;
self.process(&ctx, opt, txn, k, v).await;
}
// Everything processed ok
Ok(())
@ -158,7 +158,7 @@ impl<'a> Iterator<'a> {
false => {
// Process all prepared values
for v in mem::take(&mut self.readies) {
v.iterate(ctx, opt, exe, self).await?;
v.iterate(ctx, opt, txn, self).await?;
}
// Everything processed ok
Ok(())
@ -170,7 +170,7 @@ impl<'a> Iterator<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
thg: Option<Thing>,
val: Value,
) {
@ -183,12 +183,12 @@ impl<'a> Iterator<'a> {
// Process the document
let res = match self.stmt {
Statement::Select(_) => doc.select(ctx, opt, exe, &self.stmt).await,
Statement::Create(_) => doc.create(ctx, opt, exe, &self.stmt).await,
Statement::Update(_) => doc.update(ctx, opt, exe, &self.stmt).await,
Statement::Relate(_) => doc.relate(ctx, opt, exe, &self.stmt).await,
Statement::Delete(_) => doc.delete(ctx, opt, exe, &self.stmt).await,
Statement::Insert(_) => doc.insert(ctx, opt, exe, &self.stmt).await,
Statement::Select(_) => doc.select(ctx, opt, txn, &self.stmt).await,
Statement::Create(_) => doc.create(ctx, opt, txn, &self.stmt).await,
Statement::Update(_) => doc.update(ctx, opt, txn, &self.stmt).await,
Statement::Relate(_) => doc.relate(ctx, opt, txn, &self.stmt).await,
Statement::Delete(_) => doc.delete(ctx, opt, txn, &self.stmt).await,
Statement::Insert(_) => doc.insert(ctx, opt, txn, &self.stmt).await,
_ => unreachable!(),
};

View file

@ -9,6 +9,7 @@ mod response;
mod runtime;
mod session;
mod statement;
mod transaction;
mod variables;
pub use self::auth::*;
@ -20,6 +21,7 @@ pub use self::response::*;
pub use self::runtime::*;
pub use self::session::*;
pub use self::statement::*;
pub use self::transaction::*;
#[cfg(test)]
pub(crate) mod test;

View file

@ -1,11 +1,13 @@
use crate::ctx::Context;
use crate::dbs::executor::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use futures::lock::Mutex;
use std::sync::Arc;
pub fn mock<'a>() -> (Runtime, Options, Executor<'a>) {
pub async fn mock<'a>() -> (Runtime, Options, Transaction<'a>) {
let ctx = Context::default().freeze();
let opt = Options::default();
let exe = Executor::new();
(ctx, opt, exe)
let txn = Arc::new(Mutex::new(crate::kvs::Transaction::Mock));
(ctx, opt, txn)
}

4
src/dbs/transaction.rs Normal file
View file

@ -0,0 +1,4 @@
use futures::lock::Mutex;
use std::sync::Arc;
pub type Transaction<'a> = Arc<Mutex<crate::kvs::Transaction<'a>>>;

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<(), Error> {
match self.id {

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
Ok(())

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<(), Error> {
// Extract statement clause
@ -23,7 +23,7 @@ impl<'a> Document<'a> {
// Match clause
match cond {
Some(v) => {
match v.expr.compute(ctx, opt, exe, Some(&self.current)).await?.is_truthy() {
match v.expr.compute(ctx, opt, txn, Some(&self.current)).await?.is_truthy() {
false => Err(Error::IgnoreError),
true => Ok(()),
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,16 +11,16 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
match stm {
Statement::Select(_) => self.select(ctx, opt, exe, stm).await,
Statement::Create(_) => self.create(ctx, opt, exe, stm).await,
Statement::Update(_) => self.update(ctx, opt, exe, stm).await,
Statement::Relate(_) => self.relate(ctx, opt, exe, stm).await,
Statement::Delete(_) => self.delete(ctx, opt, exe, stm).await,
Statement::Insert(_) => self.insert(ctx, opt, exe, stm).await,
Statement::Select(_) => self.select(ctx, opt, txn, stm).await,
Statement::Create(_) => self.create(ctx, opt, txn, stm).await,
Statement::Update(_) => self.update(ctx, opt, txn, stm).await,
Statement::Relate(_) => self.relate(ctx, opt, txn, stm).await,
Statement::Delete(_) => self.delete(ctx, opt, txn, stm).await,
Statement::Insert(_) => self.insert(ctx, opt, txn, stm).await,
_ => unreachable!(),
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,26 +11,26 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
// Check value type
self.admit(ctx, opt, exe, stm).await?;
self.admit(ctx, opt, txn, stm).await?;
// Merge record data
self.merge(ctx, opt, exe, stm).await?;
self.merge(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Store index data
self.index(ctx, opt, exe, stm).await?;
self.index(ctx, opt, txn, stm).await?;
// Store record data
self.store(ctx, opt, exe, stm).await?;
self.store(ctx, opt, txn, stm).await?;
// Run table queries
self.table(ctx, opt, exe, stm).await?;
self.table(ctx, opt, txn, stm).await?;
// Run lives queries
self.lives(ctx, opt, exe, stm).await?;
self.lives(ctx, opt, txn, stm).await?;
// Run event queries
self.event(ctx, opt, exe, stm).await?;
self.event(ctx, opt, txn, stm).await?;
// Yield document
self.pluck(ctx, opt, exe, stm).await
self.pluck(ctx, opt, txn, stm).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,28 +11,28 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
// Check value type
self.admit(ctx, opt, exe, stm).await?;
self.admit(ctx, opt, txn, stm).await?;
// Check where clause
self.check(ctx, opt, exe, stm).await?;
self.check(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Erase document
self.erase(ctx, opt, exe, stm).await?;
self.erase(ctx, opt, txn, stm).await?;
// Store index data
self.index(ctx, opt, exe, stm).await?;
self.index(ctx, opt, txn, stm).await?;
// Store record data
self.store(ctx, opt, exe, stm).await?;
self.store(ctx, opt, txn, stm).await?;
// Run table queries
self.table(ctx, opt, exe, stm).await?;
self.table(ctx, opt, txn, stm).await?;
// Run lives queries
self.lives(ctx, opt, exe, stm).await?;
self.lives(ctx, opt, txn, stm).await?;
// Run event queries
self.event(ctx, opt, exe, stm).await?;
self.event(ctx, opt, txn, stm).await?;
// Yield document
self.pluck(ctx, opt, exe, stm).await
self.pluck(ctx, opt, txn, stm).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
match self.id.is_some() && self.current.is_none() {

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,9 +10,9 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
self.current.to_mut().clear(ctx, opt, exe).await
self.current.to_mut().clear(ctx, opt, txn).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
Ok(())

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
Ok(())

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,7 +11,7 @@ impl<'a> Document<'a> {
&mut self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<Value, Error> {
todo!()

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
Ok(())

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::data::Data;
@ -13,7 +13,7 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<(), Error> {
// Get the ID reference
@ -25,38 +25,38 @@ impl<'a> Document<'a> {
_ => unreachable!(),
};
// Set default field values
self.current.to_mut().def(ctx, opt, exe, id).await?;
self.current.to_mut().def(ctx, opt, txn, id).await?;
// Check for a data clause
match data {
// The statement has a data clause
Some(v) => match v {
Data::SetExpression(x) => {
for x in x.iter() {
let v = x.2.compute(ctx, opt, exe, Some(&self.current)).await?;
let v = x.2.compute(ctx, opt, txn, Some(&self.current)).await?;
match x.1 {
Operator::Equal => match v {
Value::Void => {
self.current.to_mut().del(ctx, opt, exe, &x.0).await?
self.current.to_mut().del(ctx, opt, txn, &x.0).await?
}
_ => self.current.to_mut().set(ctx, opt, exe, &x.0, v).await?,
_ => self.current.to_mut().set(ctx, opt, txn, &x.0, v).await?,
},
Operator::Inc => {
self.current.to_mut().increment(ctx, opt, exe, &x.0, v).await?
self.current.to_mut().increment(ctx, opt, txn, &x.0, v).await?
}
Operator::Dec => {
self.current.to_mut().decrement(ctx, opt, exe, &x.0, v).await?
self.current.to_mut().decrement(ctx, opt, txn, &x.0, v).await?
}
_ => unreachable!(),
}
}
}
Data::PatchExpression(v) => self.current.to_mut().patch(ctx, opt, exe, v).await?,
Data::MergeExpression(v) => self.current.to_mut().merge(ctx, opt, exe, v).await?,
Data::PatchExpression(v) => self.current.to_mut().patch(ctx, opt, txn, v).await?,
Data::MergeExpression(v) => self.current.to_mut().merge(ctx, opt, txn, v).await?,
Data::ReplaceExpression(v) => {
self.current.to_mut().replace(ctx, opt, exe, v).await?
self.current.to_mut().replace(ctx, opt, txn, v).await?
}
Data::ContentExpression(v) => {
self.current.to_mut().replace(ctx, opt, exe, v).await?
self.current.to_mut().replace(ctx, opt, txn, v).await?
}
_ => unreachable!(),
},
@ -64,7 +64,7 @@ impl<'a> Document<'a> {
None => (),
};
// Set default field values
self.current.to_mut().def(ctx, opt, exe, id).await?;
self.current.to_mut().def(ctx, opt, txn, id).await?;
// Set ASSERT and VALUE clauses
// todo!();
// Delete non-defined FIELDs

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::field::Field;
@ -14,7 +14,7 @@ impl<'a> Document<'a> {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
// Extract statement clause
@ -35,23 +35,23 @@ impl<'a> Document<'a> {
Output::None => Err(Error::IgnoreError),
Output::Null => Ok(Value::Null),
Output::Diff => Ok(self.initial.diff(&self.current, Idiom::default()).into()),
Output::After => self.current.compute(ctx, opt, exe, Some(&self.current)).await,
Output::Before => self.initial.compute(ctx, opt, exe, Some(&self.initial)).await,
Output::After => self.current.compute(ctx, opt, txn, Some(&self.current)).await,
Output::Before => self.initial.compute(ctx, opt, txn, Some(&self.initial)).await,
Output::Fields(v) => {
let mut out = match v.all() {
true => self.current.compute(ctx, opt, exe, Some(&self.current)).await?,
true => self.current.compute(ctx, opt, txn, Some(&self.current)).await?,
false => Value::base(),
};
for v in v.iter() {
match v {
Field::All => (),
Field::Alone(v) => {
let x = v.compute(ctx, opt, exe, Some(&self.current)).await?;
out.set(ctx, opt, exe, &v.to_idiom(), x).await?;
let x = v.compute(ctx, opt, txn, Some(&self.current)).await?;
out.set(ctx, opt, txn, &v.to_idiom(), x).await?;
}
Field::Alias(v, i) => {
let x = v.compute(ctx, opt, exe, Some(&self.current)).await?;
out.set(ctx, opt, exe, &i, x).await?;
let x = v.compute(ctx, opt, txn, Some(&self.current)).await?;
out.set(ctx, opt, txn, &i, x).await?;
}
}
}
@ -61,19 +61,19 @@ impl<'a> Document<'a> {
None => match stm {
Statement::Select(stm) => {
let mut out = match stm.expr.all() {
true => self.current.compute(ctx, opt, exe, Some(&self.current)).await?,
true => self.current.compute(ctx, opt, txn, Some(&self.current)).await?,
false => Value::base(),
};
for v in stm.expr.iter() {
match v {
Field::All => (),
Field::Alone(v) => {
let x = v.compute(ctx, opt, exe, Some(&self.current)).await?;
out.set(ctx, opt, exe, &v.to_idiom(), x).await?;
let x = v.compute(ctx, opt, txn, Some(&self.current)).await?;
out.set(ctx, opt, txn, &v.to_idiom(), x).await?;
}
Field::Alias(v, i) => {
let x = v.compute(ctx, opt, exe, Some(&self.current)).await?;
out.set(ctx, opt, exe, &i, x).await?;
let x = v.compute(ctx, opt, txn, Some(&self.current)).await?;
out.set(ctx, opt, txn, &i, x).await?;
}
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,28 +11,28 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
// Check value type
self.admit(ctx, opt, exe, stm).await?;
self.admit(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Merge record data
self.merge(ctx, opt, exe, stm).await?;
self.merge(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Store index data
self.index(ctx, opt, exe, stm).await?;
self.index(ctx, opt, txn, stm).await?;
// Store record data
self.store(ctx, opt, exe, stm).await?;
self.store(ctx, opt, txn, stm).await?;
// Run table queries
self.table(ctx, opt, exe, stm).await?;
self.table(ctx, opt, txn, stm).await?;
// Run lives queries
self.lives(ctx, opt, exe, stm).await?;
self.lives(ctx, opt, txn, stm).await?;
// Run event queries
self.event(ctx, opt, exe, stm).await?;
self.event(ctx, opt, txn, stm).await?;
// Yield document
self.pluck(ctx, opt, exe, stm).await
self.pluck(ctx, opt, txn, stm).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,16 +11,16 @@ impl<'a> Document<'a> {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
// Check if record exists
self.empty(ctx, opt, exe, stm).await?;
self.empty(ctx, opt, txn, stm).await?;
// Check where clause
self.check(ctx, opt, exe, stm).await?;
self.check(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Yield document
self.pluck(ctx, opt, exe, stm).await
self.pluck(ctx, opt, txn, stm).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -9,8 +9,8 @@ impl<'a> Document<'a> {
pub async fn store(
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
opt: &Options,
txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
Ok(())

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
@ -10,7 +10,7 @@ impl<'a> Document<'a> {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_stm: &Statement<'_>,
) -> Result<(), Error> {
Ok(())

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::value::Value;
@ -11,30 +11,30 @@ impl<'a> Document<'a> {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
stm: &Statement<'_>,
) -> Result<Value, Error> {
// Check value type
self.admit(ctx, opt, exe, stm).await?;
self.admit(ctx, opt, txn, stm).await?;
// Check where clause
self.check(ctx, opt, exe, stm).await?;
self.check(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Merge record data
self.merge(ctx, opt, exe, stm).await?;
self.merge(ctx, opt, txn, stm).await?;
// Check if allowed
self.allow(ctx, opt, exe, stm).await?;
self.allow(ctx, opt, txn, stm).await?;
// Store index data
self.index(ctx, opt, exe, stm).await?;
self.index(ctx, opt, txn, stm).await?;
// Store record data
self.store(ctx, opt, exe, stm).await?;
self.store(ctx, opt, txn, stm).await?;
// Run table queries
self.table(ctx, opt, exe, stm).await?;
self.table(ctx, opt, txn, stm).await?;
// Run lives queries
self.lives(ctx, opt, exe, stm).await?;
self.lives(ctx, opt, txn, stm).await?;
// Run event queries
self.event(ctx, opt, exe, stm).await?;
self.event(ctx, opt, txn, stm).await?;
// Yield document
self.pluck(ctx, opt, exe, stm).await
self.pluck(ctx, opt, txn, stm).await
}
}

View file

@ -11,12 +11,14 @@ use crate::err::Error;
use once_cell::sync::OnceCell;
pub enum Datastore {
Mock,
Mem(mem::Datastore),
File(file::Datastore),
TiKV(tikv::Datastore),
}
pub enum Transaction<'a> {
Mock,
Mem(mem::Transaction<'a>),
File(file::Transaction<'a>),
TiKV(tikv::Transaction),
@ -53,6 +55,10 @@ pub fn init(path: &str) -> Result<(), Error> {
pub async fn transaction<'a>(write: bool, lock: bool) -> Result<Transaction<'a>, Error> {
match DB.get().unwrap() {
Datastore::Mock => {
let tx = Transaction::Mock;
Ok(tx)
}
Datastore::Mem(v) => {
let tx = v.transaction(write, lock)?;
Ok(Transaction::Mem(tx))

View file

@ -8,6 +8,7 @@ impl<'a> Transaction<'a> {
// Check if closed
pub async fn closed(&self) -> bool {
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.closed(),
Transaction::File(v) => v.closed(),
Transaction::TiKV(v) => v.closed().await,
@ -16,6 +17,7 @@ impl<'a> Transaction<'a> {
// Cancel a transaction
pub async fn cancel(&mut self) -> Result<(), Error> {
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.cancel(),
Transaction::File(v) => v.cancel(),
Transaction::TiKV(v) => v.cancel().await,
@ -24,6 +26,7 @@ impl<'a> Transaction<'a> {
// Commit a transaction
pub async fn commit(&mut self) -> Result<(), Error> {
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.commit(),
Transaction::File(v) => v.commit(),
Transaction::TiKV(v) => v.commit().await,
@ -35,6 +38,7 @@ impl<'a> Transaction<'a> {
K: Into<Key>,
{
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.del(key),
Transaction::File(v) => v.del(key),
Transaction::TiKV(v) => v.del(key).await,
@ -46,6 +50,7 @@ impl<'a> Transaction<'a> {
K: Into<Key>,
{
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.exi(key),
Transaction::File(v) => v.exi(key),
Transaction::TiKV(v) => v.exi(key).await,
@ -57,6 +62,7 @@ impl<'a> Transaction<'a> {
K: Into<Key>,
{
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.get(key),
Transaction::File(v) => v.get(key),
Transaction::TiKV(v) => v.get(key).await,
@ -69,6 +75,7 @@ impl<'a> Transaction<'a> {
V: Into<Key>,
{
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.set(key, val),
Transaction::File(v) => v.set(key, val),
Transaction::TiKV(v) => v.set(key, val).await,
@ -81,6 +88,7 @@ impl<'a> Transaction<'a> {
V: Into<Key>,
{
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.put(key, val),
Transaction::File(v) => v.put(key, val),
Transaction::TiKV(v) => v.put(key, val).await,
@ -92,6 +100,7 @@ impl<'a> Transaction<'a> {
K: Into<Key>,
{
match self {
Transaction::Mock => unreachable!(),
Transaction::Mem(v) => v.scan(rng, limit),
Transaction::File(v) => v.scan(rng, limit),
Transaction::TiKV(v) => v.scan(rng, limit).await,

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::mightbespace;
use crate::sql::common::commas;
@ -117,12 +117,12 @@ impl Array {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
let mut x = Vec::new();
for v in &self.value {
match v.compute(ctx, opt, exe, doc).await {
match v.compute(ctx, opt, txn, doc).await {
Ok(v) => x.push(v),
Err(e) => return Err(e),
};

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::fnc;
use crate::sql::error::IResult;
@ -32,10 +32,10 @@ impl Expression {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
let l = self.l.compute(ctx, opt, exe, doc).await?;
let l = self.l.compute(ctx, opt, txn, doc).await?;
match self.o {
Operator::Or => match l.is_truthy() {
true => return Ok(l), // No need to continue
@ -47,7 +47,7 @@ impl Expression {
},
_ => {} // Continue
}
let r = self.r.compute(ctx, opt, exe, doc).await?;
let r = self.r.compute(ctx, opt, txn, doc).await?;
match self.o {
Operator::Or => fnc::operate::or(l, r),
Operator::And => fnc::operate::and(l, r),

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::fnc;
use crate::sql::comment::mightbespace;
@ -35,13 +35,13 @@ impl Function {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
match self {
Function::Future(ref e) => match opt.futures {
true => {
let a = e.compute(ctx, opt, exe, doc).await?;
let a = e.compute(ctx, opt, txn, doc).await?;
fnc::future::run(ctx, a)
}
false => Ok(self.to_owned().into()),
@ -51,13 +51,13 @@ impl Function {
fnc::script::run(ctx, a)
}
Function::Cast(ref s, ref e) => {
let a = e.compute(ctx, opt, exe, doc).await?;
let a = e.compute(ctx, opt, txn, doc).await?;
fnc::cast::run(ctx, s, a)
}
Function::Normal(ref s, ref e) => {
let mut a: Vec<Value> = vec![];
for v in e {
let v = v.compute(ctx, opt, exe, doc).await?;
let v = v.compute(ctx, opt, txn, doc).await?;
a.push(v);
}
fnc::run(ctx, s, a).await

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::common::commas;
use crate::sql::error::IResult;
@ -72,12 +72,12 @@ impl Idiom {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
match doc {
// There is a current document
Some(v) => v.get(ctx, opt, exe, self).await?.compute(ctx, opt, exe, doc).await,
Some(v) => v.get(ctx, opt, txn, self).await?.compute(ctx, opt, txn, doc).await,
// There isn't any document
None => Ok(Value::None),
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::mightbespace;
use crate::sql::common::{commas, escape, val_char};
@ -96,12 +96,12 @@ impl Object {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
let mut x = BTreeMap::new();
for (k, v) in &self.value {
match v.compute(ctx, opt, exe, doc).await {
match v.compute(ctx, opt, txn, doc).await {
Ok(v) => x.insert(k.clone(), v),
Err(e) => return Err(e),
};

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::error::IResult;
use crate::sql::idiom;
@ -30,7 +30,7 @@ impl Param {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Find a base variable by name
@ -40,9 +40,9 @@ impl Param {
// The base variable exists
Some(v) => {
// Process the paramater value
let res = v.compute(ctx, opt, exe, doc).await?;
let res = v.compute(ctx, opt, txn, doc).await?;
// Return the desired field
res.get(ctx, opt, exe, &self.name.next()).await
res.get(ctx, opt, txn, &self.name.next()).await
}
// The base variable does not exist
None => Ok(Value::None),

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::{comment, mightbespace};
use crate::sql::common::colons;
@ -109,24 +109,24 @@ impl Statement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
match self {
Statement::Set(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Info(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Live(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Kill(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Output(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Ifelse(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Select(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Create(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Update(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Relate(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Delete(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Insert(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Define(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Remove(ref v) => v.compute(ctx, opt, exe, doc).await,
Statement::Set(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Info(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Live(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Kill(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Output(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Ifelse(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Select(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Create(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Update(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Relate(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Delete(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Insert(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Define(ref v) => v.compute(ctx, opt, txn, doc).await,
Statement::Remove(ref v) => v.compute(ctx, opt, txn, doc).await,
_ => unreachable!(),
}
}

View file

@ -1,9 +1,9 @@
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::data::{data, Data};
@ -33,7 +33,7 @@ impl CreateStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -46,7 +46,7 @@ impl CreateStatement {
let opt = &opt.futures(false);
// Loop over the create targets
for w in self.what.0.iter() {
let v = w.compute(ctx, opt, exe, doc).await?;
let v = w.compute(ctx, opt, txn, doc).await?;
match v {
Value::Table(v) => i.produce(v),
Value::Thing(_) => i.prepare(v),
@ -60,7 +60,7 @@ impl CreateStatement {
};
}
// Output the results
i.output(ctx, opt, exe).await
i.output(ctx, opt, txn).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::algorithm::{algorithm, Algorithm};
use crate::sql::base::{base, Base};
@ -43,19 +43,19 @@ impl DefineStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
match self {
DefineStatement::Namespace(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Database(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Login(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Token(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Scope(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Table(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Event(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Field(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Index(ref v) => v.compute(ctx, opt, exe, doc).await,
DefineStatement::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Database(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Login(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Token(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Scope(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Table(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Event(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Field(ref v) => v.compute(ctx, opt, txn, doc).await,
DefineStatement::Index(ref v) => v.compute(ctx, opt, txn, doc).await,
}
}
}
@ -104,7 +104,7 @@ impl DefineNamespaceStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -148,7 +148,7 @@ impl DefineDatabaseStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -197,7 +197,7 @@ impl DefineLoginStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -295,7 +295,7 @@ impl DefineTokenStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -370,7 +370,7 @@ impl DefineScopeStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -493,7 +493,7 @@ impl DefineTableStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -624,7 +624,7 @@ impl DefineEventStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -698,7 +698,7 @@ impl DefineFieldStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -837,7 +837,7 @@ impl DefineIndexStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?

View file

@ -1,9 +1,9 @@
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::cond::{cond, Cond};
@ -34,7 +34,7 @@ impl DeleteStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -47,7 +47,7 @@ impl DeleteStatement {
let opt = &opt.futures(false);
// Loop over the delete targets
for w in self.what.0.iter() {
let v = w.compute(ctx, opt, exe, doc).await?;
let v = w.compute(ctx, opt, txn, doc).await?;
match v {
Value::Table(_) => i.prepare(v),
Value::Thing(_) => i.prepare(v),
@ -61,7 +61,7 @@ impl DeleteStatement {
};
}
// Output the results
i.output(ctx, opt, exe).await
i.output(ctx, opt, txn).await
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult;
@ -23,17 +23,17 @@ impl IfelseStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
for (ref cond, ref then) in &self.exprs {
let v = cond.compute(ctx, opt, exe, doc).await?;
let v = cond.compute(ctx, opt, txn, doc).await?;
if v.is_truthy() {
return then.compute(ctx, opt, exe, doc).await;
return then.compute(ctx, opt, txn, doc).await;
}
}
match self.close {
Some(ref v) => v.compute(ctx, opt, exe, doc).await,
Some(ref v) => v.compute(ctx, opt, txn, doc).await,
None => Ok(Value::None),
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult;
@ -25,7 +25,7 @@ impl InfoStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?

View file

@ -1,9 +1,9 @@
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::data::{single, update, values, Data};
@ -37,7 +37,7 @@ impl InsertStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -54,7 +54,7 @@ impl InsertStatement {
todo!() // TODO: loop over each
}
Data::SingleExpression(v) => {
let v = v.compute(ctx, opt, exe, doc).await?;
let v = v.compute(ctx, opt, txn, doc).await?;
match v {
Value::Array(v) => v.value.into_iter().for_each(|v| i.prepare(v)),
Value::Object(_) => i.prepare(v),
@ -68,7 +68,7 @@ impl InsertStatement {
_ => unreachable!(),
}
// Output the results
i.output(ctx, opt, exe).await
i.output(ctx, opt, txn).await
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult;
@ -20,7 +20,7 @@ impl KillStatement {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
todo!()

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::cond::{cond, Cond};
@ -30,7 +30,7 @@ impl LiveStatement {
&self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
todo!()

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult;
@ -19,13 +19,13 @@ impl OutputStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Ensure futures are processed
let opt = &opt.futures(true);
// Process the output value
self.what.compute(ctx, opt, exe, doc).await
self.what.compute(ctx, opt, txn, doc).await
}
}

View file

@ -1,9 +1,9 @@
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::mightbespace;
use crate::sql::comment::shouldbespace;
@ -40,7 +40,7 @@ impl RelateStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -53,7 +53,7 @@ impl RelateStatement {
let opt = &opt.futures(false);
// Loop over the select targets
for w in self.from.0.iter() {
let v = w.compute(ctx, opt, exe, doc).await?;
let v = w.compute(ctx, opt, txn, doc).await?;
match v {
Value::Table(_) => i.prepare(v),
Value::Thing(_) => i.prepare(v),
@ -67,7 +67,7 @@ impl RelateStatement {
};
}
// Output the results
i.output(ctx, opt, exe).await
i.output(ctx, opt, txn).await
}
}

View file

@ -1,7 +1,7 @@
use crate::dbs::Executor;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::base::{base, Base};
use crate::sql::comment::shouldbespace;
@ -33,19 +33,19 @@ impl RemoveStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
match self {
RemoveStatement::Namespace(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Database(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Login(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Token(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Scope(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Table(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Event(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Field(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Index(ref v) => v.compute(ctx, opt, exe, doc).await,
RemoveStatement::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Database(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Login(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Token(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Scope(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Table(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Event(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Field(ref v) => v.compute(ctx, opt, txn, doc).await,
RemoveStatement::Index(ref v) => v.compute(ctx, opt, txn, doc).await,
}
}
}
@ -94,7 +94,7 @@ impl RemoveNamespaceStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -138,7 +138,7 @@ impl RemoveDatabaseStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -183,7 +183,7 @@ impl RemoveLoginStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -237,7 +237,7 @@ impl RemoveTokenStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -290,7 +290,7 @@ impl RemoveScopeStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -334,7 +334,7 @@ impl RemoveTableStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -379,7 +379,7 @@ impl RemoveEventStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -430,7 +430,7 @@ impl RemoveFieldStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -481,7 +481,7 @@ impl RemoveIndexStatement {
&self,
_ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
_doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?

View file

@ -1,9 +1,9 @@
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::cond::{cond, Cond};
@ -68,7 +68,7 @@ impl SelectStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -87,7 +87,7 @@ impl SelectStatement {
let opt = &opt.futures(true);
// Loop over the select targets
for w in self.what.0.iter() {
let v = w.compute(ctx, opt, exe, doc).await?;
let v = w.compute(ctx, opt, txn, doc).await?;
match v {
Value::Table(_) => i.prepare(v),
Value::Thing(_) => i.prepare(v),
@ -97,7 +97,7 @@ impl SelectStatement {
};
}
// Output the results
i.output(ctx, opt, exe).await
i.output(ctx, opt, txn).await
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::mightbespace;
use crate::sql::comment::shouldbespace;
@ -24,10 +24,10 @@ impl SetStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
self.what.compute(ctx, opt, exe, doc).await
self.what.compute(ctx, opt, txn, doc).await
}
}

View file

@ -1,9 +1,9 @@
use crate::dbs::Executor;
use crate::dbs::Iterator;
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::cond::{cond, Cond};
@ -36,7 +36,7 @@ impl UpdateStatement {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
// Allowed to run?
@ -49,7 +49,7 @@ impl UpdateStatement {
let opt = &opt.futures(false);
// Loop over the update targets
for w in self.what.0.iter() {
let v = w.compute(ctx, opt, exe, doc).await?;
let v = w.compute(ctx, opt, txn, doc).await?;
match v {
Value::Table(_) => i.prepare(v),
Value::Thing(_) => i.prepare(v),
@ -63,7 +63,7 @@ impl UpdateStatement {
};
}
// Output the results
i.output(ctx, opt, exe).await
i.output(ctx, opt, txn).await
}
}

View file

@ -1,7 +1,7 @@
use crate::ctx::Context;
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::error::IResult;
use crate::sql::statements::create::{create, CreateStatement};
@ -43,12 +43,12 @@ impl Subquery {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&Value>,
) -> Result<Value, Error> {
match self {
Subquery::Value(ref v) => v.compute(ctx, opt, exe, doc).await,
Subquery::Ifelse(ref v) => v.compute(ctx, opt, exe, doc).await,
Subquery::Value(ref v) => v.compute(ctx, opt, txn, doc).await,
Subquery::Ifelse(ref v) => v.compute(ctx, opt, txn, doc).await,
Subquery::Select(ref v) => {
// Duplicate options
let opt = opt.dive()?;
@ -62,15 +62,15 @@ impl Subquery {
// Prepare context
let ctx = ctx.freeze();
// Process subquery
let res = v.compute(&ctx, &opt, exe, doc).await?;
let res = v.compute(&ctx, &opt, txn, doc).await?;
// Process result
match v.limit() {
1 => match v.expr.single() {
Some(v) => res.first(&ctx, &opt, exe).await?.get(&ctx, &opt, exe, &v).await,
None => res.first(&ctx, &opt, exe).await,
Some(v) => res.first(&ctx, &opt, txn).await?.get(&ctx, &opt, txn, &v).await,
None => res.first(&ctx, &opt, txn).await,
},
_ => match v.expr.single() {
Some(v) => res.get(&ctx, &opt, exe, &v).await,
Some(v) => res.get(&ctx, &opt, txn, &v).await,
None => res.ok(),
},
}
@ -88,7 +88,7 @@ impl Subquery {
// Prepare context
let ctx = ctx.freeze();
// Process subquery
match v.compute(&ctx, &opt, exe, doc).await? {
match v.compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
_ => Ok(v.into()),
@ -109,7 +109,7 @@ impl Subquery {
// Prepare context
let ctx = ctx.freeze();
// Process subquery
match v.compute(&ctx, &opt, exe, doc).await? {
match v.compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
_ => Ok(v.into()),
@ -130,7 +130,7 @@ impl Subquery {
// Prepare context
let ctx = ctx.freeze();
// Process subquery
match v.compute(&ctx, &opt, exe, doc).await? {
match v.compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
_ => Ok(v.into()),
@ -151,7 +151,7 @@ impl Subquery {
// Prepare context
let ctx = ctx.freeze();
// Process subquery
match v.compute(&ctx, &opt, exe, doc).await? {
match v.compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
_ => Ok(v.into()),
@ -172,7 +172,7 @@ impl Subquery {
// Prepare context
let ctx = ctx.freeze();
// Process subquery
match v.compute(&ctx, &opt, exe, doc).await? {
match v.compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
_ => Ok(v.into()),

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::array::Array;
use crate::sql::idiom::Idiom;
@ -11,11 +11,11 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
) -> Result<(), Error> {
let val = Value::from(Array::default());
self.set(ctx, opt, exe, path, val).await
self.set(ctx, opt, txn, path, val).await
}
}
@ -28,21 +28,21 @@ mod tests {
#[tokio::test]
async fn array_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::default();
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("[]");
val.array(&ctx, &opt, &exe, &idi).await.unwrap();
val.array(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn array_path() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: [] }");
val.array(&ctx, &opt, &exe, &idi).await.unwrap();
val.array(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::value::Value;
@ -9,7 +9,7 @@ impl Value {
&mut self,
_ctx: &Runtime,
_opt: &Options,
_exe: &Executor<'_>,
_txn: &Transaction<'_>,
) -> Result<(), Error> {
*self = Value::base();
Ok(())
@ -25,19 +25,19 @@ mod tests {
#[tokio::test]
async fn clear_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{}");
val.clear(&ctx, &opt, &exe).await.unwrap();
val.clear(&ctx, &opt, &txn).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn clear_path() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{}");
val.clear(&ctx, &opt, &exe).await.unwrap();
val.clear(&ctx, &opt, &txn).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::number::Number;
@ -11,22 +11,22 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
val: Value,
) -> Result<(), Error> {
match self.get(ctx, opt, exe, path).await? {
match self.get(ctx, opt, txn, path).await? {
Value::Number(v) => match val {
Value::Number(x) => self.set(ctx, opt, exe, path, Value::from(v - x)).await,
Value::Number(x) => self.set(ctx, opt, txn, path, Value::from(v - x)).await,
_ => Ok(()),
},
Value::Array(v) => match val {
Value::Array(x) => self.set(ctx, opt, exe, path, Value::from(v - x)).await,
x => self.set(ctx, opt, exe, path, Value::from(v - x)).await,
Value::Array(x) => self.set(ctx, opt, txn, path, Value::from(v - x)).await,
x => self.set(ctx, opt, txn, path, Value::from(v - x)).await,
},
Value::None => match val {
Value::Number(x) => {
self.set(ctx, opt, exe, path, Value::from(Number::from(0) - x)).await
self.set(ctx, opt, txn, path, Value::from(Number::from(0) - x)).await
}
_ => Ok(()),
},
@ -44,51 +44,51 @@ mod tests {
#[tokio::test]
async fn dec_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("other");
let mut val = Value::parse("{ test: 100 }");
let res = Value::parse("{ test: 100, other: -10 }");
val.decrement(&ctx, &opt, &exe, &idi, Value::from(10)).await.unwrap();
val.decrement(&ctx, &opt, &txn, &idi, Value::from(10)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn dec_number() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: 100 }");
let res = Value::parse("{ test: 90 }");
val.decrement(&ctx, &opt, &exe, &idi, Value::from(10)).await.unwrap();
val.decrement(&ctx, &opt, &txn, &idi, Value::from(10)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn dec_array_number() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test[1]");
let mut val = Value::parse("{ test: [100, 200, 300] }");
let res = Value::parse("{ test: [100, 190, 300] }");
val.decrement(&ctx, &opt, &exe, &idi, Value::from(10)).await.unwrap();
val.decrement(&ctx, &opt, &txn, &idi, Value::from(10)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn dec_array_value() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: [100, 200, 300] }");
let res = Value::parse("{ test: [100, 300] }");
val.decrement(&ctx, &opt, &exe, &idi, Value::from(200)).await.unwrap();
val.decrement(&ctx, &opt, &txn, &idi, Value::from(200)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn dec_array_array() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: [100, 200, 300] }");
let res = Value::parse("{ test: [200] }");
val.decrement(&ctx, &opt, &exe, &idi, Value::parse("[100, 300]")).await.unwrap();
val.decrement(&ctx, &opt, &txn, &idi, Value::parse("[100, 300]")).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::part::Part;
@ -25,16 +25,16 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
val: Option<&Thing>,
) -> Result<(), Error> {
match val {
Some(id) => {
let id = id.clone();
let md = id.clone();
self.set(ctx, opt, exe, &RID, id.into()).await?;
self.set(ctx, opt, exe, &MTB, md.tb.into()).await?;
self.set(ctx, opt, exe, &MID, md.id.into()).await?;
self.set(ctx, opt, txn, &RID, id.into()).await?;
self.set(ctx, opt, txn, &MTB, md.tb.into()).await?;
self.set(ctx, opt, txn, &MID, md.id.into()).await?;
Ok(())
}
None => unreachable!(),

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::array::Abolish;
use crate::sql::idiom::Idiom;
@ -16,7 +16,7 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
) -> Result<(), Error> {
match path.parts.first() {
@ -30,7 +30,7 @@ impl Value {
Ok(())
}
_ => match v.value.get_mut(&p.name) {
Some(v) if v.is_some() => v.del(ctx, opt, exe, &path.next()).await,
Some(v) if v.is_some() => v.del(ctx, opt, txn, &path.next()).await,
_ => Ok(()),
},
},
@ -45,7 +45,7 @@ impl Value {
}
_ => {
let pth = path.next();
let fut = v.value.iter_mut().map(|v| v.del(&ctx, opt, exe, &pth));
let fut = v.value.iter_mut().map(|v| v.del(&ctx, opt, txn, &pth));
try_join_all(fut).await?;
Ok(())
}
@ -58,7 +58,7 @@ impl Value {
Ok(())
}
_ => match v.value.first_mut() {
Some(v) => v.del(ctx, opt, exe, &path.next()).await,
Some(v) => v.del(ctx, opt, txn, &path.next()).await,
None => Ok(()),
},
},
@ -70,7 +70,7 @@ impl Value {
Ok(())
}
_ => match v.value.last_mut() {
Some(v) => v.del(ctx, opt, exe, &path.next()).await,
Some(v) => v.del(ctx, opt, txn, &path.next()).await,
None => Ok(()),
},
},
@ -83,7 +83,7 @@ impl Value {
}
_ => match path.parts.len() {
_ => match v.value.get_mut(i.to_usize()) {
Some(v) => v.del(ctx, opt, exe, &path.next()).await,
Some(v) => v.del(ctx, opt, txn, &path.next()).await,
None => Ok(()),
},
},
@ -92,7 +92,7 @@ impl Value {
1 => {
let mut m = HashMap::new();
for (i, v) in v.value.iter().enumerate() {
if w.compute(ctx, opt, exe, Some(&v)).await?.is_truthy() {
if w.compute(ctx, opt, txn, Some(&v)).await?.is_truthy() {
m.insert(i, ());
};
}
@ -102,8 +102,8 @@ impl Value {
_ => {
let pth = path.next();
for v in &mut v.value {
if w.compute(ctx, opt, exe, Some(&v)).await?.is_truthy() {
v.del(ctx, opt, exe, &pth).await?;
if w.compute(ctx, opt, txn, Some(&v)).await?.is_truthy() {
v.del(ctx, opt, txn, &pth).await?;
}
}
Ok(())
@ -129,101 +129,101 @@ mod tests {
#[tokio::test]
async fn del_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::default();
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: null, something: 123 } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_reset() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_basic() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: null } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_wrong() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something.wrong");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: null, something: 123 } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_other() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.other.something");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: null, something: 123 } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_array() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1]");
let mut val = Value::parse("{ test: { something: [123, 456, 789] } }");
let res = Value::parse("{ test: { something: [123, 789] } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_array_field() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1].age");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 34 }, { }] } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_array_fields() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[*].age");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ }, { }] } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_array_where_field() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[WHERE age > 35].age");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 34 }, { }] } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn del_array_where_fields() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[WHERE age > 35]");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 34 }] } }");
val.del(&ctx, &opt, &exe, &idi).await.unwrap();
val.del(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,11 +1,17 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::sql::idiom::Idiom;
use crate::sql::value::Value;
impl Value {
pub fn fetch(self, _ctx: &Runtime, _opt: &Options, _exe: &Executor<'_>, _path: &Idiom) -> Self {
pub fn fetch(
self,
_ctx: &Runtime,
_opt: &Options,
_txn: &Transaction<'_>,
_path: &Idiom,
) -> Self {
self
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::part::Part;
@ -11,8 +11,8 @@ impl Value {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
) -> Result<Self, Error> {
self.get(ctx, opt, exe, &Idiom::from(vec![Part::First])).await
self.get(ctx, opt, txn, &Idiom::from(vec![Part::First])).await
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::field::{Field, Fields};
use crate::sql::idiom::Idiom;
@ -16,7 +16,7 @@ impl Value {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
) -> Result<Self, Error> {
match path.parts.first() {
@ -25,7 +25,7 @@ impl Value {
// Current path part is an object
Value::Object(v) => match p {
Part::Field(p) => match v.value.get(&p.name) {
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
Some(v) => v.get(ctx, opt, txn, &path.next()).await,
None => Ok(Value::None),
},
_ => Ok(Value::None),
@ -34,27 +34,27 @@ impl Value {
Value::Array(v) => match p {
Part::All => {
let pth = path.next();
let fut = v.value.iter().map(|v| v.get(&ctx, opt, exe, &pth));
let fut = v.value.iter().map(|v| v.get(&ctx, opt, txn, &pth));
try_join_all(fut).await.map(|v| v.into())
}
Part::First => match v.value.first() {
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
Some(v) => v.get(ctx, opt, txn, &path.next()).await,
None => Ok(Value::None),
},
Part::Last => match v.value.last() {
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
Some(v) => v.get(ctx, opt, txn, &path.next()).await,
None => Ok(Value::None),
},
Part::Index(i) => match v.value.get(i.to_usize()) {
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
Some(v) => v.get(ctx, opt, txn, &path.next()).await,
None => Ok(Value::None),
},
Part::Where(w) => {
let pth = path.next();
let mut a = Vec::new();
for v in &v.value {
if w.compute(ctx, opt, exe, Some(&v)).await?.is_truthy() {
a.push(v.get(ctx, opt, exe, &pth).await?)
if w.compute(ctx, opt, txn, Some(&v)).await?.is_truthy() {
a.push(v.get(ctx, opt, txn, &pth).await?)
}
}
Ok(a.into())
@ -72,11 +72,11 @@ impl Value {
what: Values(vec![Value::Thing(v.clone())]),
..SelectStatement::default()
};
stm.compute(ctx, opt, exe, None)
stm.compute(ctx, opt, txn, None)
.await?
.first(ctx, opt, exe)
.first(ctx, opt, txn)
.await?
.get(ctx, opt, exe, &path)
.get(ctx, opt, txn, &path)
.await
}
},
@ -99,28 +99,28 @@ mod tests {
#[tokio::test]
async fn get_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::default();
let val = Value::parse("{ test: { other: null, something: 123 } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn get_basic() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something");
let val = Value::parse("{ test: { other: null, something: 123 } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, Value::from(123));
}
#[tokio::test]
async fn get_thing() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.other");
let val = Value::parse("{ test: { other: test:tobie, something: 123 } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(
res,
Value::from(Thing {
@ -132,19 +132,19 @@ mod tests {
#[tokio::test]
async fn get_array() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1]");
let val = Value::parse("{ test: { something: [123, 456, 789] } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, Value::from(456));
}
#[tokio::test]
async fn get_array_thing() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1]");
let val = Value::parse("{ test: { something: [test:tobie, test:jaime] } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(
res,
Value::from(Thing {
@ -156,37 +156,37 @@ mod tests {
#[tokio::test]
async fn get_array_field() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1].age");
let val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, Value::from(36));
}
#[tokio::test]
async fn get_array_fields() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[*].age");
let val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, Value::from(vec![34, 36]));
}
#[tokio::test]
async fn get_array_where_field() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[WHERE age > 35].age");
let val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, Value::from(vec![36]));
}
#[tokio::test]
async fn get_array_where_fields() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[WHERE age > 35]");
let val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = val.get(&ctx, &opt, &exe, &idi).await.unwrap();
let res = val.get(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(
res,
Value::from(vec![Value::from(map! {

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::number::Number;
@ -11,25 +11,25 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
val: Value,
) -> Result<(), Error> {
match self.get(ctx, opt, exe, path).await? {
match self.get(ctx, opt, txn, path).await? {
Value::Number(v) => match val {
Value::Number(x) => self.set(ctx, opt, exe, path, Value::from(v + x)).await,
Value::Number(x) => self.set(ctx, opt, txn, path, Value::from(v + x)).await,
_ => Ok(()),
},
Value::Array(v) => match val {
Value::Array(x) => self.set(ctx, opt, exe, path, Value::from(v + x)).await,
x => self.set(ctx, opt, exe, path, Value::from(v + x)).await,
Value::Array(x) => self.set(ctx, opt, txn, path, Value::from(v + x)).await,
x => self.set(ctx, opt, txn, path, Value::from(v + x)).await,
},
Value::None => match val {
Value::Number(x) => {
self.set(ctx, opt, exe, path, Value::from(Number::from(0) + x)).await
self.set(ctx, opt, txn, path, Value::from(Number::from(0) + x)).await
}
Value::Array(x) => self.set(ctx, opt, exe, path, Value::from(x)).await,
x => self.set(ctx, opt, exe, path, Value::from(vec![x])).await,
Value::Array(x) => self.set(ctx, opt, txn, path, Value::from(x)).await,
x => self.set(ctx, opt, txn, path, Value::from(vec![x])).await,
},
_ => Ok(()),
}
@ -45,53 +45,51 @@ mod tests {
#[tokio::test]
async fn inc_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("other");
let mut val = Value::parse("{ test: 100 }");
let res = Value::parse("{ test: 100, other: +10 }");
val.increment(&ctx, &opt, &exe, &idi, Value::from(10)).await.unwrap();
val.increment(&ctx, &opt, &txn, &idi, Value::from(10)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn inc_number() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: 100 }");
let res = Value::parse("{ test: 110 }");
val.increment(&ctx, &opt, &exe, &idi, Value::from(10)).await.unwrap();
val.increment(&ctx, &opt, &txn, &idi, Value::from(10)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn inc_array_number() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test[1]");
let mut val = Value::parse("{ test: [100, 200, 300] }");
let res = Value::parse("{ test: [100, 210, 300] }");
val.increment(&ctx, &opt, &exe, &idi, Value::from(10)).await.unwrap();
val.increment(&ctx, &opt, &txn, &idi, Value::from(10)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn inc_array_value() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: [100, 200, 300] }");
let res = Value::parse("{ test: [100, 200, 300] }");
val.increment(&ctx, &opt, &exe, &idi, Value::from(200)).await.unwrap();
val.increment(&ctx, &opt, &txn, &idi, Value::from(200)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn inc_array_array() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: [100, 200, 300] }");
let res = Value::parse("{ test: [100, 200, 300, 400, 500] }");
val.increment(&ctx, &opt, &exe, &idi, Value::parse("[100, 300, 400, 500]"))
.await
.unwrap();
val.increment(&ctx, &opt, &txn, &idi, Value::parse("[100, 300, 400, 500]")).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::part::Part;
@ -11,8 +11,8 @@ impl Value {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
) -> Result<Self, Error> {
self.get(ctx, opt, exe, &Idiom::from(vec![Part::Last])).await
self.get(ctx, opt, txn, &Idiom::from(vec![Part::Last])).await
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::value::Value;
@ -9,13 +9,13 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
val: &Value,
) -> Result<(), Error> {
match val.compute(ctx, opt, exe, Some(self)).await? {
match val.compute(ctx, opt, txn, Some(self)).await? {
Value::Object(v) => {
for (k, v) in v.value.into_iter() {
self.set(ctx, opt, exe, &k.into(), v).await?;
self.set(ctx, opt, txn, &k.into(), v).await?;
}
Ok(())
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::object::Object;
@ -11,11 +11,11 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
) -> Result<(), Error> {
let val = Value::from(Object::default());
self.set(ctx, opt, exe, path, val).await
self.set(ctx, opt, txn, path, val).await
}
}
@ -28,21 +28,21 @@ mod tests {
#[tokio::test]
async fn object_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::default();
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{}");
val.object(&ctx, &opt, &exe, &idi).await.unwrap();
val.object(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn object_path() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: {} }");
val.object(&ctx, &opt, &exe, &idi).await.unwrap();
val.object(&ctx, &opt, &txn, &idi).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::array::Array;
use crate::sql::operation::Op;
@ -11,25 +11,25 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
val: &Array,
) -> Result<(), Error> {
for o in val.to_operations()?.into_iter() {
match o.op {
Op::Add => match self.get(ctx, opt, exe, &o.path).await? {
Value::Array(_) => self.increment(ctx, opt, exe, &o.path, o.value).await?,
_ => self.set(ctx, opt, exe, &o.path, o.value).await?,
Op::Add => match self.get(ctx, opt, txn, &o.path).await? {
Value::Array(_) => self.increment(ctx, opt, txn, &o.path, o.value).await?,
_ => self.set(ctx, opt, txn, &o.path, o.value).await?,
},
Op::Remove => self.del(ctx, opt, exe, &o.path).await?,
Op::Replace => self.set(ctx, opt, exe, &o.path, o.value).await?,
Op::Remove => self.del(ctx, opt, txn, &o.path).await?,
Op::Replace => self.set(ctx, opt, txn, &o.path, o.value).await?,
Op::Change => match o.value {
Value::Strand(p) => match self.get(ctx, opt, exe, &o.path).await? {
Value::Strand(p) => match self.get(ctx, opt, txn, &o.path).await? {
Value::Strand(v) => {
let mut dmp = dmp::new();
let mut pch = dmp.patch_from_text(p.value);
let (txt, _) = dmp.patch_apply(&mut pch, &v.value);
let txt = txt.into_iter().collect::<String>();
self.set(ctx, opt, exe, &o.path, Value::from(txt)).await?;
self.set(ctx, opt, txn, &o.path, Value::from(txt)).await?;
()
}
_ => (),
@ -52,85 +52,85 @@ mod tests {
#[tokio::test]
async fn patch_add_simple() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let ops = Array::parse("[{ op: 'add', path: '/temp', value: true }]");
let res = Value::parse("{ test: { other: null, something: 123 }, temp: true }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_remove_simple() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 }, temp: true }");
let ops = Array::parse("[{ op: 'remove', path: '/temp' }]");
let res = Value::parse("{ test: { other: null, something: 123 } }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_replace_simple() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 }, temp: true }");
let ops = Array::parse("[{ op: 'replace', path: '/temp', value: 'text' }]");
let res = Value::parse("{ test: { other: null, something: 123 }, temp: 'text' }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_change_simple() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 }, temp: 'test' }");
let ops = Array::parse(
"[{ op: 'change', path: '/temp', value: '@@ -1,4 +1,4 @@\n te\n-s\n+x\n t\n' }]",
);
let res = Value::parse("{ test: { other: null, something: 123 }, temp: 'text' }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_add_embedded() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let ops = Array::parse("[{ op: 'add', path: '/temp/test', value: true }]");
let res = Value::parse("{ test: { other: null, something: 123 }, temp: { test: true } }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_remove_embedded() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 }, temp: true }");
let ops = Array::parse("[{ op: 'remove', path: '/test/other' }]");
let res = Value::parse("{ test: { something: 123 }, temp: true }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_replace_embedded() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 }, temp: true }");
let ops = Array::parse("[{ op: 'replace', path: '/test/other', value: 'text' }]");
let res = Value::parse("{ test: { other: 'text', something: 123 }, temp: true }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn patch_change_embedded() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: 'test', something: 123 }, temp: true }");
let ops = Array::parse(
"[{ op: 'change', path: '/test/other', value: '@@ -1,4 +1,4 @@\n te\n-s\n+x\n t\n' }]",
);
let res = Value::parse("{ test: { other: 'text', something: 123 }, temp: true }");
val.patch(&ctx, &opt, &exe, &ops).await.unwrap();
val.patch(&ctx, &opt, &txn, &ops).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::value::Value;
@ -9,11 +9,11 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
val: &Value,
) -> Result<(), Error> {
// Clear all entries
match val.compute(ctx, opt, exe, Some(self)).await? {
match val.compute(ctx, opt, txn, Some(self)).await? {
Value::Object(v) => {
*self = Value::from(v);
Ok(())
@ -32,11 +32,11 @@ mod tests {
#[tokio::test]
async fn replace() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ other: true }");
let obj = Value::parse("{ other: true }");
val.replace(&ctx, &opt, &exe, &obj).await.unwrap();
val.replace(&ctx, &opt, &txn, &obj).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::idiom::Idiom;
use crate::sql::part::Part;
@ -14,7 +14,7 @@ impl Value {
&mut self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
path: &Idiom,
val: Value,
) -> Result<(), Error> {
@ -24,10 +24,10 @@ impl Value {
// Current path part is an object
Value::Object(v) => match p {
Part::Field(p) => match v.value.get_mut(&p.name) {
Some(v) if v.is_some() => v.set(ctx, opt, exe, &path.next(), val).await,
Some(v) if v.is_some() => v.set(ctx, opt, txn, &path.next(), val).await,
_ => {
let mut obj = Value::base();
obj.set(ctx, opt, exe, &path.next(), val).await?;
obj.set(ctx, opt, txn, &path.next(), val).await?;
v.insert(&p.name, obj);
Ok(())
}
@ -39,27 +39,27 @@ impl Value {
Part::All => {
let pth = path.next();
let fut =
v.value.iter_mut().map(|v| v.set(ctx, opt, exe, &pth, val.clone()));
v.value.iter_mut().map(|v| v.set(ctx, opt, txn, &pth, val.clone()));
try_join_all(fut).await?;
Ok(())
}
Part::First => match v.value.first_mut() {
Some(v) => v.set(ctx, opt, exe, &path.next(), val).await,
Some(v) => v.set(ctx, opt, txn, &path.next(), val).await,
None => Ok(()),
},
Part::Last => match v.value.last_mut() {
Some(v) => v.set(ctx, opt, exe, &path.next(), val).await,
Some(v) => v.set(ctx, opt, txn, &path.next(), val).await,
None => Ok(()),
},
Part::Index(i) => match v.value.get_mut(i.to_usize()) {
Some(v) => v.set(ctx, opt, exe, &path.next(), val).await,
Some(v) => v.set(ctx, opt, txn, &path.next(), val).await,
None => Ok(()),
},
Part::Where(w) => {
let pth = path.next();
for v in &mut v.value {
if w.compute(ctx, opt, exe, Some(&v)).await?.is_truthy() {
v.set(ctx, opt, exe, &pth, val.clone()).await?;
if w.compute(ctx, opt, txn, Some(&v)).await?.is_truthy() {
v.set(ctx, opt, txn, &pth, val.clone()).await?;
}
}
Ok(())
@ -69,12 +69,12 @@ impl Value {
// Current path part is empty
Value::Null => {
*self = Value::base();
self.set(ctx, opt, exe, path, val).await
self.set(ctx, opt, txn, path, val).await
}
// Current path part is empty
Value::None => {
*self = Value::base();
self.set(ctx, opt, exe, path, val).await
self.set(ctx, opt, txn, path, val).await
}
// Ignore everything else
_ => Ok(()),
@ -97,131 +97,131 @@ mod tests {
#[tokio::test]
async fn set_none() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::default();
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("999");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_empty() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::None;
let res = Value::parse("{ test: 999 }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_blank() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something");
let mut val = Value::None;
let res = Value::parse("{ test: { something: 999 } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_reset() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: 999 }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_basic() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: null, something: 999 } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_allow() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something.allow");
let mut val = Value::parse("{ test: { other: null } }");
let res = Value::parse("{ test: { other: null, something: { allow: 999 } } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_wrong() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something.wrong");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: null, something: 123 } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_other() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.other.something");
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
let res = Value::parse("{ test: { other: { something: 999 }, something: 123 } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_array() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1]");
let mut val = Value::parse("{ test: { something: [123, 456, 789] } }");
let res = Value::parse("{ test: { something: [123, 999, 789] } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(999)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(999)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_array_field() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[1].age");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 34 }, { age: 21 }] } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(21)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(21)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_array_fields() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[*].age");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 21 }, { age: 21 }] } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(21)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(21)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_array_where_field() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[WHERE age > 35].age");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 34 }, { age: 21 }] } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(21)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(21)).await.unwrap();
assert_eq!(res, val);
}
#[tokio::test]
async fn set_array_where_fields() {
let (ctx, opt, exe) = mock();
let (ctx, opt, txn) = mock().await;
let idi = Idiom::parse("test.something[WHERE age > 35]");
let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
let res = Value::parse("{ test: { something: [{ age: 34 }, 21] } }");
val.set(&ctx, &opt, &exe, &idi, Value::from(21)).await.unwrap();
val.set(&ctx, &opt, &txn, &idi, Value::from(21)).await.unwrap();
assert_eq!(res, val);
}
}

View file

@ -1,6 +1,6 @@
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::array::{array, Array};
use crate::sql::common::commas;
@ -810,7 +810,7 @@ impl Value {
&self,
ctx: &Runtime,
opt: &Options,
exe: &Executor<'_>,
txn: &Transaction<'_>,
doc: Option<&'async_recursion Value>,
) -> Result<Value, Error> {
match self {
@ -819,13 +819,13 @@ impl Value {
Value::Null => Ok(Value::Null),
Value::True => Ok(Value::True),
Value::False => Ok(Value::False),
Value::Param(v) => v.compute(ctx, opt, exe, doc).await,
Value::Idiom(v) => v.compute(ctx, opt, exe, doc).await,
Value::Array(v) => v.compute(ctx, opt, exe, doc).await,
Value::Object(v) => v.compute(ctx, opt, exe, doc).await,
Value::Function(v) => v.compute(ctx, opt, exe, doc).await,
Value::Subquery(v) => v.compute(ctx, opt, exe, doc).await,
Value::Expression(v) => v.compute(ctx, opt, exe, doc).await,
Value::Param(v) => v.compute(ctx, opt, txn, doc).await,
Value::Idiom(v) => v.compute(ctx, opt, txn, doc).await,
Value::Array(v) => v.compute(ctx, opt, txn, doc).await,
Value::Object(v) => v.compute(ctx, opt, txn, doc).await,
Value::Function(v) => v.compute(ctx, opt, txn, doc).await,
Value::Subquery(v) => v.compute(ctx, opt, txn, doc).await,
Value::Expression(v) => v.compute(ctx, opt, txn, doc).await,
_ => Ok(self.to_owned()),
}
}