Convert all processing code to async
This commit is contained in:
parent
db9960fcbe
commit
3126251a65
41 changed files with 1092 additions and 963 deletions
|
@ -19,7 +19,7 @@ pub async fn execute(txt: &str, session: Session, vars: Variables) -> Result<Res
|
|||
// Process all statements
|
||||
exe.ns = session.ns;
|
||||
exe.db = session.db;
|
||||
exe.execute(ctx, ast)
|
||||
exe.execute(ctx, ast).await
|
||||
}
|
||||
|
||||
pub async fn process(ast: Query, session: Session, vars: Variables) -> Result<Responses, Error> {
|
||||
|
@ -30,7 +30,7 @@ pub async fn process(ast: Query, session: Session, vars: Variables) -> Result<Re
|
|||
// Process all statements
|
||||
exe.ns = session.ns;
|
||||
exe.db = session.db;
|
||||
exe.execute(ctx, ast)
|
||||
exe.execute(ctx, ast).await
|
||||
}
|
||||
|
||||
pub fn export(session: Session) -> Result<String, Error> {
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::dbs::response::{Response, Responses};
|
|||
use crate::dbs::Auth;
|
||||
use crate::dbs::Level;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Process;
|
||||
use crate::dbs::Runtime;
|
||||
use crate::err::Error;
|
||||
use crate::sql::query::Query;
|
||||
|
@ -47,7 +46,7 @@ impl Executor {
|
|||
todo!()
|
||||
}
|
||||
|
||||
pub fn execute(&mut self, mut ctx: Runtime, qry: Query) -> Result<Responses, Error> {
|
||||
pub async fn execute(&mut self, mut ctx: Runtime, qry: Query) -> Result<Responses, Error> {
|
||||
// Initialise array of responses
|
||||
let mut out: Vec<Response> = vec![];
|
||||
// Create a new options
|
||||
|
@ -75,25 +74,25 @@ impl Executor {
|
|||
}
|
||||
// Begin a new transaction
|
||||
Statement::Begin(stm) => {
|
||||
let res = stm.process(&ctx, &opt, self, None);
|
||||
let res = stm.compute(&ctx, &opt, self, None).await;
|
||||
self.err = res.err();
|
||||
continue;
|
||||
}
|
||||
// Cancel a running transaction
|
||||
Statement::Cancel(stm) => {
|
||||
let res = stm.process(&ctx, &opt, self, None);
|
||||
let res = stm.compute(&ctx, &opt, self, None).await;
|
||||
self.err = res.err();
|
||||
continue;
|
||||
}
|
||||
// Commit a running transaction
|
||||
Statement::Commit(stm) => {
|
||||
let res = stm.process(&ctx, &opt, self, None);
|
||||
let res = stm.compute(&ctx, &opt, self, None).await;
|
||||
self.err = res.err();
|
||||
continue;
|
||||
}
|
||||
// Process param definition statements
|
||||
Statement::Set(stm) => {
|
||||
match stm.process(&ctx, &opt, self, None) {
|
||||
match stm.compute(&ctx, &opt, self, None).await {
|
||||
Ok(val) => {
|
||||
let mut new = Context::new(&ctx);
|
||||
let key = stm.name.to_owned();
|
||||
|
@ -115,7 +114,7 @@ impl Executor {
|
|||
ctx = new.freeze();
|
||||
}
|
||||
// Process statement
|
||||
let res = stm.process(&ctx, &opt, self, None);
|
||||
let res = stm.compute(&ctx, &opt, self, None).await;
|
||||
// Catch statement timeout
|
||||
if let Some(timeout) = stm.timeout() {
|
||||
if ctx.is_timedout() {
|
||||
|
|
|
@ -3,7 +3,6 @@ mod dbs;
|
|||
mod executor;
|
||||
mod iterator;
|
||||
mod options;
|
||||
mod process;
|
||||
mod response;
|
||||
mod runtime;
|
||||
mod session;
|
||||
|
@ -13,7 +12,6 @@ pub use self::dbs::*;
|
|||
pub use self::executor::*;
|
||||
pub use self::iterator::*;
|
||||
pub use self::options::*;
|
||||
pub use self::process::*;
|
||||
pub use self::response::*;
|
||||
pub use self::runtime::*;
|
||||
pub use self::session::*;
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
use crate::dbs::executor::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
||||
pub trait Process {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error>;
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -92,6 +91,27 @@ impl Array {
|
|||
}
|
||||
}
|
||||
|
||||
impl Array {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
let mut x = Vec::new();
|
||||
for v in &self.value {
|
||||
match v.compute(ctx, opt, exe, doc).await {
|
||||
Ok(v) => x.push(v),
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
}
|
||||
Ok(Value::Array(Array {
|
||||
value: x,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Array {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -102,29 +122,6 @@ impl fmt::Display for Array {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Array {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
self.value
|
||||
.iter()
|
||||
.map(|v| match v.process(ctx, opt, exe, doc) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => Err(e),
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map(|v| {
|
||||
Value::Array(Array {
|
||||
value: v,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Array {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
@ -190,6 +187,38 @@ impl ops::Sub for Array {
|
|||
|
||||
// ------------------------------
|
||||
|
||||
pub trait Abolish<T> {
|
||||
fn abolish<F>(&mut self, f: F)
|
||||
where
|
||||
F: FnMut(usize) -> bool;
|
||||
}
|
||||
|
||||
impl<T> Abolish<T> for Vec<T> {
|
||||
fn abolish<F>(&mut self, mut f: F)
|
||||
where
|
||||
F: FnMut(usize) -> bool,
|
||||
{
|
||||
let len = self.len();
|
||||
let mut del = 0;
|
||||
{
|
||||
let v = &mut **self;
|
||||
|
||||
for i in 0..len {
|
||||
if f(i) {
|
||||
del += 1;
|
||||
} else if del > 0 {
|
||||
v.swap(i - del, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if del > 0 {
|
||||
self.truncate(len - del);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
|
||||
pub trait Uniq<T> {
|
||||
fn uniq(self) -> Vec<T>;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -28,21 +27,15 @@ impl Default for Expression {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Expression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {} {}", self.l, self.o, self.r)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Expression {
|
||||
fn process(
|
||||
impl Expression {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
let l = self.l.process(ctx, opt, exe, doc)?;
|
||||
let l = self.l.compute(ctx, opt, exe, doc).await?;
|
||||
match self.o {
|
||||
Operator::Or => match l.is_truthy() {
|
||||
true => return Ok(l), // No need to continue
|
||||
|
@ -54,7 +47,7 @@ impl dbs::Process for Expression {
|
|||
},
|
||||
_ => {} // Continue
|
||||
}
|
||||
let r = self.r.process(ctx, opt, exe, doc)?;
|
||||
let r = self.r.compute(ctx, opt, exe, doc).await?;
|
||||
match self.o {
|
||||
Operator::Or => fnc::operate::or(l, r),
|
||||
Operator::And => fnc::operate::and(l, r),
|
||||
|
@ -91,6 +84,12 @@ impl dbs::Process for Expression {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Expression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {} {}", self.l, self.o, self.r)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expression(i: &str) -> IResult<&str, Expression> {
|
||||
let (i, l) = single(i)?;
|
||||
let (i, o) = operator(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -31,6 +30,42 @@ impl PartialOrd for Function {
|
|||
}
|
||||
}
|
||||
|
||||
impl Function {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
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?;
|
||||
fnc::future::run(ctx, a)
|
||||
}
|
||||
false => Ok(self.to_owned().into()),
|
||||
},
|
||||
Function::Script(ref s) => {
|
||||
let a = s.to_owned();
|
||||
fnc::script::run(ctx, a)
|
||||
}
|
||||
Function::Cast(ref s, ref e) => {
|
||||
let a = e.compute(ctx, opt, exe, 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?;
|
||||
a.push(v);
|
||||
}
|
||||
fnc::run(ctx, s, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Function {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
|
@ -47,42 +82,6 @@ impl fmt::Display for Function {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Function {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
Function::Future(ref e) => match opt.futures {
|
||||
true => {
|
||||
let a = e.process(ctx, opt, exe, doc)?;
|
||||
fnc::future::run(ctx, a)
|
||||
}
|
||||
false => Ok(self.to_owned().into()),
|
||||
},
|
||||
Function::Script(ref s) => {
|
||||
let a = s.to_owned();
|
||||
fnc::script::run(ctx, a)
|
||||
}
|
||||
Function::Cast(ref s, ref e) => {
|
||||
let a = e.process(ctx, opt, exe, doc)?;
|
||||
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.process(ctx, opt, exe, doc)?;
|
||||
a.push(v);
|
||||
}
|
||||
fnc::run(ctx, s, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn function(i: &str) -> IResult<&str, Function> {
|
||||
alt((casts, langs, future, normal))(i)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -50,6 +49,23 @@ impl Idiom {
|
|||
}
|
||||
}
|
||||
|
||||
impl Idiom {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match doc {
|
||||
// There is a current document
|
||||
Some(v) => v.get(ctx, opt, exe, self).await.ok(),
|
||||
// There isn't any document
|
||||
None => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Idiom {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -68,23 +84,6 @@ impl fmt::Display for Idiom {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Idiom {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match doc {
|
||||
// There is a current document
|
||||
Some(v) => v.get(ctx, opt, exe, self).ok(),
|
||||
// There isn't any document
|
||||
None => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used in a DEFINE FIELD and DEFINE INDEX clause
|
||||
pub fn local(i: &str) -> IResult<&str, Idiom> {
|
||||
let (i, p) = first(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -53,6 +52,27 @@ impl Object {
|
|||
}
|
||||
}
|
||||
|
||||
impl Object {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
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 {
|
||||
Ok(v) => x.insert(k.clone(), v),
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
}
|
||||
Ok(Value::Object(Object {
|
||||
value: x,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Object {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -67,29 +87,6 @@ impl fmt::Display for Object {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Object {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
self.value
|
||||
.iter()
|
||||
.map(|(k, v)| match v.process(ctx, opt, exe, doc) {
|
||||
Ok(v) => Ok((k.clone(), v)),
|
||||
Err(e) => Err(e),
|
||||
})
|
||||
.collect::<Result<BTreeMap<_, _>, _>>()
|
||||
.map(|v| {
|
||||
Value::Object(Object {
|
||||
value: v,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Object {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -26,17 +25,11 @@ impl From<Idiom> for Param {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Param {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "${}", &self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Param {
|
||||
fn process(
|
||||
impl Param {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -47,9 +40,9 @@ impl dbs::Process for Param {
|
|||
// The base variable exists
|
||||
Some(v) => {
|
||||
// Process the paramater value
|
||||
let res = v.process(ctx, opt, exe, doc)?;
|
||||
let res = v.compute(ctx, opt, exe, doc).await?;
|
||||
// Return the desired field
|
||||
res.get(ctx, opt, exe, &self.name.next()).ok()
|
||||
res.get(ctx, opt, exe, &self.name.next()).await.ok()
|
||||
}
|
||||
// The base variable does not exist
|
||||
None => Ok(Value::None),
|
||||
|
@ -59,6 +52,12 @@ impl dbs::Process for Param {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Param {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "${}", &self.name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn param(i: &str) -> IResult<&str, Param> {
|
||||
let (i, _) = tag("$")(i)?;
|
||||
let (i, v) = idiom::param(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -111,6 +110,38 @@ impl Statement {
|
|||
}
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match *self {
|
||||
Statement::Use(ref v) => v.compute(ctx, opt, exe, doc).await,
|
||||
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::Begin(ref v) => v.compute(ctx, opt, exe, doc).await,
|
||||
Statement::Cancel(ref v) => v.compute(ctx, opt, exe, doc).await,
|
||||
Statement::Commit(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,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Statement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -137,38 +168,6 @@ impl fmt::Display for Statement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Statement {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match *self {
|
||||
Statement::Use(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Set(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Info(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Live(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Kill(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Begin(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Cancel(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Commit(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Output(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Ifelse(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Select(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Create(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Update(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Relate(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Delete(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Insert(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Define(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Statement::Remove(ref v) => v.process(ctx, opt, exe, doc),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn statement(i: &str) -> IResult<&str, Statement> {
|
||||
delimited(
|
||||
mightbespace,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -16,17 +15,11 @@ use std::fmt;
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct BeginStatement;
|
||||
|
||||
impl fmt::Display for BeginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "BEGIN TRANSACTION")
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for BeginStatement {
|
||||
fn process(
|
||||
impl BeginStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
_opt: &Options,
|
||||
_opt: &Options<'_>,
|
||||
_exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -34,6 +27,12 @@ impl dbs::Process for BeginStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BeginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "BEGIN TRANSACTION")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin(i: &str) -> IResult<&str, BeginStatement> {
|
||||
alt((begin_query, begin_basic))(i)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -16,17 +15,11 @@ use std::fmt;
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CancelStatement;
|
||||
|
||||
impl fmt::Display for CancelStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "CANCEL TRANSACTION")
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for CancelStatement {
|
||||
fn process(
|
||||
impl CancelStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
_opt: &Options,
|
||||
_opt: &Options<'_>,
|
||||
_exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -34,6 +27,12 @@ impl dbs::Process for CancelStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CancelStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "CANCEL TRANSACTION")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cancel(i: &str) -> IResult<&str, CancelStatement> {
|
||||
alt((cancel_query, cancel_basic))(i)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -16,17 +15,11 @@ use std::fmt;
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CommitStatement;
|
||||
|
||||
impl fmt::Display for CommitStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "COMMIT TRANSACTION")
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for CommitStatement {
|
||||
fn process(
|
||||
impl CommitStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
_opt: &Options,
|
||||
_opt: &Options<'_>,
|
||||
_exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -34,6 +27,12 @@ impl dbs::Process for CommitStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CommitStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "COMMIT TRANSACTION")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn commit(i: &str) -> IResult<&str, CommitStatement> {
|
||||
alt((commit_query, commit_basic))(i)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Iterator;
|
||||
use crate::dbs::Level;
|
||||
|
@ -28,27 +27,11 @@ pub struct CreateStatement {
|
|||
pub timeout: Option<Timeout>,
|
||||
}
|
||||
|
||||
impl fmt::Display for CreateStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "CREATE {}", self.what)?;
|
||||
if let Some(ref v) = self.data {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for CreateStatement {
|
||||
fn process(
|
||||
impl CreateStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -62,7 +45,7 @@ impl dbs::Process for CreateStatement {
|
|||
let opt = &opt.futures(false);
|
||||
// Loop over the create targets
|
||||
for w in self.what.0.iter() {
|
||||
match w.process(ctx, opt, exe, doc)? {
|
||||
match w.compute(ctx, opt, exe, doc).await? {
|
||||
Value::Table(v) => {
|
||||
i.process_table(ctx, exe, v);
|
||||
}
|
||||
|
@ -90,6 +73,22 @@ impl dbs::Process for CreateStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CreateStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "CREATE {}", self.what)?;
|
||||
if let Some(ref v) = self.data {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(i: &str) -> IResult<&str, CreateStatement> {
|
||||
let (i, _) = tag_no_case("CREATE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Level;
|
||||
use crate::dbs::Options;
|
||||
|
@ -38,6 +37,28 @@ pub enum DefineStatement {
|
|||
Index(DefineIndexStatement),
|
||||
}
|
||||
|
||||
impl DefineStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
|
@ -54,28 +75,6 @@ impl fmt::Display for DefineStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineStatement {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
DefineStatement::Namespace(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Database(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Login(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Token(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Scope(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Table(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Event(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Field(ref v) => v.process(ctx, opt, exe, doc),
|
||||
DefineStatement::Index(ref v) => v.process(ctx, opt, exe, doc),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn define(i: &str) -> IResult<&str, DefineStatement> {
|
||||
alt((
|
||||
map(namespace, |v| DefineStatement::Namespace(v)),
|
||||
|
@ -99,17 +98,11 @@ pub struct DefineNamespaceStatement {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineNamespaceStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE NAMESPACE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineNamespaceStatement {
|
||||
fn process(
|
||||
impl DefineNamespaceStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -120,6 +113,12 @@ impl dbs::Process for DefineNamespaceStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineNamespaceStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE NAMESPACE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -143,17 +142,11 @@ pub struct DefineDatabaseStatement {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineDatabaseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE DATABASE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineDatabaseStatement {
|
||||
fn process(
|
||||
impl DefineDatabaseStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -164,6 +157,12 @@ impl dbs::Process for DefineDatabaseStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineDatabaseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE DATABASE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -192,24 +191,11 @@ pub struct DefineLoginStatement {
|
|||
pub hash: Option<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineLoginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE LOGIN {} ON {}", self.name, self.base)?;
|
||||
if let Some(ref v) = self.pass {
|
||||
write!(f, " PASSWORD {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.hash {
|
||||
write!(f, " PASSHASH {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineLoginStatement {
|
||||
fn process(
|
||||
impl DefineLoginStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -224,6 +210,19 @@ impl dbs::Process for DefineLoginStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineLoginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE LOGIN {} ON {}", self.name, self.base)?;
|
||||
if let Some(ref v) = self.pass {
|
||||
write!(f, " PASSWORD {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.hash {
|
||||
write!(f, " PASSHASH {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn login(i: &str) -> IResult<&str, DefineLoginStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -290,21 +289,11 @@ pub struct DefineTokenStatement {
|
|||
pub code: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineTokenStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"DEFINE TOKEN {} ON {} TYPE {} VALUE {}",
|
||||
self.name, self.base, self.kind, self.code
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineTokenStatement {
|
||||
fn process(
|
||||
impl DefineTokenStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -319,6 +308,16 @@ impl dbs::Process for DefineTokenStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineTokenStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"DEFINE TOKEN {} ON {} TYPE {} VALUE {}",
|
||||
self.name, self.base, self.kind, self.code
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -365,6 +364,21 @@ pub struct DefineScopeStatement {
|
|||
pub connect: Option<Value>,
|
||||
}
|
||||
|
||||
impl DefineScopeStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineScopeStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE SCOPE {}", self.name)?;
|
||||
|
@ -384,21 +398,6 @@ impl fmt::Display for DefineScopeStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineScopeStatement {
|
||||
fn process(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn scope(i: &str) -> IResult<&str, DefineScopeStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -488,6 +487,21 @@ pub struct DefineTableStatement {
|
|||
pub permissions: Permissions,
|
||||
}
|
||||
|
||||
impl DefineTableStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineTableStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE TABLE {}", self.name)?;
|
||||
|
@ -508,21 +522,6 @@ impl fmt::Display for DefineTableStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineTableStatement {
|
||||
fn process(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn table(i: &str) -> IResult<&str, DefineTableStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -619,21 +618,11 @@ pub struct DefineEventStatement {
|
|||
pub then: Values,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineEventStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"DEFINE EVENT {} ON {} WHEN {} THEN {}",
|
||||
self.name, self.what, self.when, self.then
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineEventStatement {
|
||||
fn process(
|
||||
impl DefineEventStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -644,6 +633,16 @@ impl dbs::Process for DefineEventStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineEventStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"DEFINE EVENT {} ON {} WHEN {} THEN {}",
|
||||
self.name, self.what, self.when, self.then
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn event(i: &str) -> IResult<&str, DefineEventStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -693,6 +692,21 @@ pub struct DefineFieldStatement {
|
|||
pub permissions: Permissions,
|
||||
}
|
||||
|
||||
impl DefineFieldStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineFieldStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE FIELD {} ON {}", self.name, self.what)?;
|
||||
|
@ -710,21 +724,6 @@ impl fmt::Display for DefineFieldStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineFieldStatement {
|
||||
fn process(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn field(i: &str) -> IResult<&str, DefineFieldStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -832,21 +831,11 @@ pub struct DefineIndexStatement {
|
|||
pub uniq: bool,
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineIndexStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE INDEX {} ON {} COLUMNS {}", self.name, self.what, self.cols)?;
|
||||
if self.uniq == true {
|
||||
write!(f, " UNIQUE")?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DefineIndexStatement {
|
||||
fn process(
|
||||
impl DefineIndexStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -857,6 +846,16 @@ impl dbs::Process for DefineIndexStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineIndexStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE INDEX {} ON {} COLUMNS {}", self.name, self.what, self.cols)?;
|
||||
if self.uniq == true {
|
||||
write!(f, " UNIQUE")?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn index(i: &str) -> IResult<&str, DefineIndexStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Iterator;
|
||||
use crate::dbs::Level;
|
||||
|
@ -29,27 +28,11 @@ pub struct DeleteStatement {
|
|||
pub timeout: Option<Timeout>,
|
||||
}
|
||||
|
||||
impl fmt::Display for DeleteStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DELETE {}", self.what)?;
|
||||
if let Some(ref v) = self.cond {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for DeleteStatement {
|
||||
fn process(
|
||||
impl DeleteStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -63,7 +46,7 @@ impl dbs::Process for DeleteStatement {
|
|||
let opt = &opt.futures(false);
|
||||
// Loop over the delete targets
|
||||
for w in self.what.0.iter() {
|
||||
match w.process(ctx, opt, exe, doc)? {
|
||||
match w.compute(ctx, opt, exe, doc).await? {
|
||||
Value::Table(v) => {
|
||||
i.process_table(ctx, exe, v);
|
||||
}
|
||||
|
@ -91,6 +74,22 @@ impl dbs::Process for DeleteStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DeleteStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DELETE {}", self.what)?;
|
||||
if let Some(ref v) = self.cond {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete(i: &str) -> IResult<&str, DeleteStatement> {
|
||||
let (i, _) = tag_no_case("DELETE")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("FROM"))))(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -19,6 +18,27 @@ pub struct IfelseStatement {
|
|||
pub close: Option<Value>,
|
||||
}
|
||||
|
||||
impl IfelseStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
for (ref cond, ref then) in &self.exprs {
|
||||
let v = cond.compute(ctx, opt, exe, doc).await?;
|
||||
if v.is_truthy() {
|
||||
return then.compute(ctx, opt, exe, doc).await;
|
||||
}
|
||||
}
|
||||
match self.close {
|
||||
Some(ref v) => v.compute(ctx, opt, exe, doc).await,
|
||||
None => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for IfelseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -38,27 +58,6 @@ impl fmt::Display for IfelseStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for IfelseStatement {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
for (ref cond, ref then) in &self.exprs {
|
||||
let v = cond.process(ctx, opt, exe, doc)?;
|
||||
if v.is_truthy() {
|
||||
return then.process(ctx, opt, exe, doc);
|
||||
}
|
||||
}
|
||||
match self.close {
|
||||
Some(ref v) => v.process(ctx, opt, exe, doc),
|
||||
None => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ifelse(i: &str) -> IResult<&str, IfelseStatement> {
|
||||
let (i, exprs) = separated_list0(split, exprs)(i)?;
|
||||
let (i, close) = opt(close)(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Level;
|
||||
use crate::dbs::Options;
|
||||
|
@ -21,22 +20,11 @@ pub enum InfoStatement {
|
|||
Table(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for InfoStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
InfoStatement::Namespace => write!(f, "INFO FOR NAMESPACE"),
|
||||
InfoStatement::Database => write!(f, "INFO FOR DATABASE"),
|
||||
InfoStatement::Scope(ref s) => write!(f, "INFO FOR SCOPE {}", s),
|
||||
InfoStatement::Table(ref t) => write!(f, "INFO FOR TABLE {}", t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for InfoStatement {
|
||||
fn process(
|
||||
impl InfoStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -52,6 +40,17 @@ impl dbs::Process for InfoStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InfoStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
InfoStatement::Namespace => write!(f, "INFO FOR NAMESPACE"),
|
||||
InfoStatement::Database => write!(f, "INFO FOR DATABASE"),
|
||||
InfoStatement::Scope(ref s) => write!(f, "INFO FOR SCOPE {}", s),
|
||||
InfoStatement::Table(ref t) => write!(f, "INFO FOR TABLE {}", t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn info(i: &str) -> IResult<&str, InfoStatement> {
|
||||
let (i, _) = tag_no_case("INFO")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Iterator;
|
||||
use crate::dbs::Level;
|
||||
|
@ -32,28 +31,11 @@ pub struct InsertStatement {
|
|||
pub timeout: Option<Timeout>,
|
||||
}
|
||||
|
||||
impl fmt::Display for InsertStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "INSERT")?;
|
||||
if self.ignore {
|
||||
write!(f, " IGNORE")?
|
||||
}
|
||||
write!(f, " INTO {} {}", self.into, self.data)?;
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for InsertStatement {
|
||||
fn process(
|
||||
impl InsertStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -71,7 +53,7 @@ impl dbs::Process for InsertStatement {
|
|||
Data::ValuesExpression(_) => {
|
||||
todo!() // TODO: loop over each
|
||||
}
|
||||
Data::SingleExpression(v) => match v.process(ctx, opt, exe, doc)? {
|
||||
Data::SingleExpression(v) => match v.compute(ctx, opt, exe, doc).await? {
|
||||
Value::Array(v) => {
|
||||
i.process_array(ctx, exe, v);
|
||||
}
|
||||
|
@ -91,6 +73,23 @@ impl dbs::Process for InsertStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InsertStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "INSERT")?;
|
||||
if self.ignore {
|
||||
write!(f, " IGNORE")?
|
||||
}
|
||||
write!(f, " INTO {} {}", self.into, self.data)?;
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(i: &str) -> IResult<&str, InsertStatement> {
|
||||
let (i, _) = tag_no_case("INSERT")(i)?;
|
||||
let (i, ignore) = opt(preceded(shouldbespace, tag_no_case("IGNORE")))(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -16,17 +15,11 @@ pub struct KillStatement {
|
|||
pub id: Ident,
|
||||
}
|
||||
|
||||
impl fmt::Display for KillStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "KILL {}", self.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for KillStatement {
|
||||
fn process(
|
||||
impl KillStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
_opt: &Options,
|
||||
_opt: &Options<'_>,
|
||||
_exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -34,6 +27,12 @@ impl dbs::Process for KillStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for KillStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "KILL {}", self.id)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kill(i: &str) -> IResult<&str, KillStatement> {
|
||||
let (i, _) = tag_no_case("KILL")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -26,6 +25,18 @@ pub struct LiveStatement {
|
|||
pub fetch: Option<Fetchs>,
|
||||
}
|
||||
|
||||
impl LiveStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
_opt: &Options<'_>,
|
||||
_exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LiveStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "LIVE SELECT {} FROM {}", self.expr, self.what)?;
|
||||
|
@ -39,18 +50,6 @@ impl fmt::Display for LiveStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for LiveStatement {
|
||||
fn process(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
_opt: &Options,
|
||||
_exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn live(i: &str) -> IResult<&str, LiveStatement> {
|
||||
let (i, _) = tag_no_case("LIVE SELECT")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Level;
|
||||
use crate::dbs::Options;
|
||||
|
@ -23,21 +22,11 @@ pub struct OptionStatement {
|
|||
pub what: bool,
|
||||
}
|
||||
|
||||
impl fmt::Display for OptionStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.what {
|
||||
write!(f, "OPTION {}", self.name)
|
||||
} else {
|
||||
write!(f, "OPTION {} = FALSE", self.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for OptionStatement {
|
||||
fn process(
|
||||
impl OptionStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -48,6 +37,16 @@ impl dbs::Process for OptionStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OptionStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.what {
|
||||
write!(f, "OPTION {}", self.name)
|
||||
} else {
|
||||
write!(f, "OPTION {} = FALSE", self.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn option(i: &str) -> IResult<&str, OptionStatement> {
|
||||
let (i, _) = tag_no_case("OPTION")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -15,24 +14,24 @@ pub struct OutputStatement {
|
|||
pub what: Value,
|
||||
}
|
||||
|
||||
impl fmt::Display for OutputStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "RETURN {}", self.what)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for OutputStatement {
|
||||
fn process(
|
||||
impl OutputStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Ensure futures are processed
|
||||
let opt = &opt.futures(true);
|
||||
// Process the output value
|
||||
self.what.process(ctx, opt, exe, doc)
|
||||
self.what.compute(ctx, opt, exe, doc).await
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OutputStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "RETURN {}", self.what)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Iterator;
|
||||
use crate::dbs::Level;
|
||||
|
@ -35,30 +34,11 @@ pub struct RelateStatement {
|
|||
pub timeout: Option<Timeout>,
|
||||
}
|
||||
|
||||
impl fmt::Display for RelateStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "RELATE {} -> {} -> {}", self.from, self.kind, self.with)?;
|
||||
if self.uniq {
|
||||
write!(f, " UNIQUE")?
|
||||
}
|
||||
if let Some(ref v) = self.data {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RelateStatement {
|
||||
fn process(
|
||||
impl RelateStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -70,7 +50,7 @@ impl dbs::Process for RelateStatement {
|
|||
let opt = &opt.futures(false);
|
||||
// Loop over the select targets
|
||||
for f in self.from.0.iter() {
|
||||
match f.process(ctx, opt, exe, doc)? {
|
||||
match f.compute(ctx, opt, exe, doc).await? {
|
||||
Value::Table(v) => {
|
||||
i.process_table(ctx, exe, v);
|
||||
}
|
||||
|
@ -98,6 +78,25 @@ impl dbs::Process for RelateStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RelateStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "RELATE {} -> {} -> {}", self.from, self.kind, self.with)?;
|
||||
if self.uniq {
|
||||
write!(f, " UNIQUE")?
|
||||
}
|
||||
if let Some(ref v) = self.data {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn relate(i: &str) -> IResult<&str, RelateStatement> {
|
||||
let (i, _) = tag_no_case("RELATE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Level;
|
||||
use crate::dbs::Options;
|
||||
|
@ -29,6 +28,28 @@ pub enum RemoveStatement {
|
|||
Index(RemoveIndexStatement),
|
||||
}
|
||||
|
||||
impl RemoveStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
|
@ -45,28 +66,6 @@ impl fmt::Display for RemoveStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveStatement {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
RemoveStatement::Namespace(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Database(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Login(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Token(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Scope(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Table(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Event(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Field(ref v) => v.process(ctx, opt, exe, doc),
|
||||
RemoveStatement::Index(ref v) => v.process(ctx, opt, exe, doc),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(i: &str) -> IResult<&str, RemoveStatement> {
|
||||
alt((
|
||||
map(namespace, |v| RemoveStatement::Namespace(v)),
|
||||
|
@ -90,17 +89,11 @@ pub struct RemoveNamespaceStatement {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveNamespaceStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE NAMESPACE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveNamespaceStatement {
|
||||
fn process(
|
||||
impl RemoveNamespaceStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -111,6 +104,12 @@ impl dbs::Process for RemoveNamespaceStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveNamespaceStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE NAMESPACE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn namespace(i: &str) -> IResult<&str, RemoveNamespaceStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -134,17 +133,11 @@ pub struct RemoveDatabaseStatement {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveDatabaseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE DATABASE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveDatabaseStatement {
|
||||
fn process(
|
||||
impl RemoveDatabaseStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -155,6 +148,12 @@ impl dbs::Process for RemoveDatabaseStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveDatabaseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE DATABASE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn database(i: &str) -> IResult<&str, RemoveDatabaseStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -179,17 +178,11 @@ pub struct RemoveLoginStatement {
|
|||
pub base: Base,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveLoginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE LOGIN {} ON {}", self.name, self.base)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveLoginStatement {
|
||||
fn process(
|
||||
impl RemoveLoginStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -204,6 +197,12 @@ impl dbs::Process for RemoveLoginStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveLoginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE LOGIN {} ON {}", self.name, self.base)
|
||||
}
|
||||
}
|
||||
|
||||
fn login(i: &str) -> IResult<&str, RemoveLoginStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -233,17 +232,11 @@ pub struct RemoveTokenStatement {
|
|||
pub base: Base,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveTokenStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE TOKEN {} ON {}", self.name, self.base)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveTokenStatement {
|
||||
fn process(
|
||||
impl RemoveTokenStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -258,6 +251,12 @@ impl dbs::Process for RemoveTokenStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveTokenStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE TOKEN {} ON {}", self.name, self.base)
|
||||
}
|
||||
}
|
||||
|
||||
fn token(i: &str) -> IResult<&str, RemoveTokenStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -286,17 +285,11 @@ pub struct RemoveScopeStatement {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveScopeStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE SCOPE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveScopeStatement {
|
||||
fn process(
|
||||
impl RemoveScopeStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -307,6 +300,12 @@ impl dbs::Process for RemoveScopeStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveScopeStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE SCOPE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn scope(i: &str) -> IResult<&str, RemoveScopeStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -330,17 +329,11 @@ pub struct RemoveTableStatement {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveTableStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE TABLE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveTableStatement {
|
||||
fn process(
|
||||
impl RemoveTableStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -351,6 +344,12 @@ impl dbs::Process for RemoveTableStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveTableStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE TABLE {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn table(i: &str) -> IResult<&str, RemoveTableStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -375,17 +374,11 @@ pub struct RemoveEventStatement {
|
|||
pub what: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveEventStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE EVENT {} ON {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveEventStatement {
|
||||
fn process(
|
||||
impl RemoveEventStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -396,6 +389,12 @@ impl dbs::Process for RemoveEventStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveEventStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE EVENT {} ON {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
fn event(i: &str) -> IResult<&str, RemoveEventStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -426,17 +425,11 @@ pub struct RemoveFieldStatement {
|
|||
pub what: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveFieldStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE FIELD {} ON {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveFieldStatement {
|
||||
fn process(
|
||||
impl RemoveFieldStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -447,6 +440,12 @@ impl dbs::Process for RemoveFieldStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveFieldStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE FIELD {} ON {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
fn field(i: &str) -> IResult<&str, RemoveFieldStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -477,17 +476,11 @@ pub struct RemoveIndexStatement {
|
|||
pub what: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveIndexStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE INDEX {} ON {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for RemoveIndexStatement {
|
||||
fn process(
|
||||
impl RemoveIndexStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -498,6 +491,12 @@ impl dbs::Process for RemoveIndexStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveIndexStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE INDEX {} ON {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
fn index(i: &str) -> IResult<&str, RemoveIndexStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Iterator;
|
||||
use crate::dbs::Level;
|
||||
|
@ -63,6 +62,58 @@ impl SelectStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl SelectStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::No)?;
|
||||
// Create a new iterator
|
||||
let mut i = Iterator::new();
|
||||
// Pass in statement config
|
||||
i.expr = Some(&self.expr);
|
||||
i.cond = self.cond.as_ref();
|
||||
i.split = self.split.as_ref();
|
||||
i.group = self.group.as_ref();
|
||||
i.order = self.order.as_ref();
|
||||
i.limit = self.limit.as_ref();
|
||||
i.start = self.start.as_ref();
|
||||
// Ensure futures are processed
|
||||
let opt = &opt.futures(true);
|
||||
// Specify the document version
|
||||
let opt = &opt.version(self.version.as_ref());
|
||||
// Loop over the select targets
|
||||
for w in self.what.0.iter() {
|
||||
match w.compute(ctx, opt, exe, doc).await? {
|
||||
Value::Table(v) => {
|
||||
i.process_table(ctx, exe, v);
|
||||
}
|
||||
Value::Thing(v) => {
|
||||
i.process_thing(ctx, exe, v);
|
||||
}
|
||||
Value::Model(v) => {
|
||||
i.process_model(ctx, exe, v);
|
||||
}
|
||||
Value::Array(v) => {
|
||||
i.process_array(ctx, exe, v);
|
||||
}
|
||||
Value::Object(v) => {
|
||||
i.process_object(ctx, exe, v);
|
||||
}
|
||||
v => {
|
||||
i.process_value(ctx, exe, v);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Output the results
|
||||
i.output(ctx, exe)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SelectStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "SELECT {} FROM {}", self.expr, self.what)?;
|
||||
|
@ -97,58 +148,6 @@ impl fmt::Display for SelectStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for SelectStatement {
|
||||
fn process(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
exe.check(opt, Level::No)?;
|
||||
// Create a new iterator
|
||||
let mut i = Iterator::new();
|
||||
// Pass in statement config
|
||||
i.expr = Some(&self.expr);
|
||||
i.cond = self.cond.as_ref();
|
||||
i.split = self.split.as_ref();
|
||||
i.group = self.group.as_ref();
|
||||
i.order = self.order.as_ref();
|
||||
i.limit = self.limit.as_ref();
|
||||
i.start = self.start.as_ref();
|
||||
// Ensure futures are processed
|
||||
let opt = &opt.futures(true);
|
||||
// Specify the document version
|
||||
let opt = &opt.version(self.version.as_ref());
|
||||
// Loop over the select targets
|
||||
for w in self.what.0.iter() {
|
||||
match w.process(ctx, opt, exe, doc)? {
|
||||
Value::Table(v) => {
|
||||
i.process_table(ctx, exe, v);
|
||||
}
|
||||
Value::Thing(v) => {
|
||||
i.process_thing(ctx, exe, v);
|
||||
}
|
||||
Value::Model(v) => {
|
||||
i.process_model(ctx, exe, v);
|
||||
}
|
||||
Value::Array(v) => {
|
||||
i.process_array(ctx, exe, v);
|
||||
}
|
||||
Value::Object(v) => {
|
||||
i.process_object(ctx, exe, v);
|
||||
}
|
||||
v => {
|
||||
i.process_value(ctx, exe, v);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Output the results
|
||||
i.output(ctx, exe)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select(i: &str) -> IResult<&str, SelectStatement> {
|
||||
let (i, _) = tag_no_case("SELECT")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -20,21 +19,21 @@ pub struct SetStatement {
|
|||
pub what: Value,
|
||||
}
|
||||
|
||||
impl fmt::Display for SetStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "LET ${} = {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for SetStatement {
|
||||
fn process(
|
||||
impl SetStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
self.what.process(ctx, opt, exe, doc)
|
||||
self.what.compute(ctx, opt, exe, doc).await
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SetStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "LET ${} = {}", self.name, self.what)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Iterator;
|
||||
use crate::dbs::Level;
|
||||
|
@ -31,30 +30,11 @@ pub struct UpdateStatement {
|
|||
pub timeout: Option<Timeout>,
|
||||
}
|
||||
|
||||
impl fmt::Display for UpdateStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "UPDATE {}", self.what)?;
|
||||
if let Some(ref v) = self.data {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.cond {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for UpdateStatement {
|
||||
fn process(
|
||||
impl UpdateStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -69,7 +49,7 @@ impl dbs::Process for UpdateStatement {
|
|||
let opt = &opt.futures(false);
|
||||
// Loop over the update targets
|
||||
for w in self.what.0.iter() {
|
||||
match w.process(ctx, opt, exe, doc)? {
|
||||
match w.compute(ctx, opt, exe, doc).await? {
|
||||
Value::Table(v) => {
|
||||
i.process_table(ctx, exe, v);
|
||||
}
|
||||
|
@ -97,6 +77,25 @@ impl dbs::Process for UpdateStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for UpdateStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "UPDATE {}", self.what)?;
|
||||
if let Some(ref v) = self.data {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.cond {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.output {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
if let Some(ref v) = self.timeout {
|
||||
write!(f, " {}", v)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(i: &str) -> IResult<&str, UpdateStatement> {
|
||||
let (i, _) = tag_no_case("UPDATE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Auth;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
|
@ -21,24 +20,11 @@ pub struct UseStatement {
|
|||
pub db: Option<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for UseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "USE")?;
|
||||
if let Some(ref ns) = self.ns {
|
||||
write!(f, " NS {}", ns)?;
|
||||
}
|
||||
if let Some(ref db) = self.db {
|
||||
write!(f, " DB {}", db)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for UseStatement {
|
||||
fn process(
|
||||
impl UseStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -73,6 +59,19 @@ impl dbs::Process for UseStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for UseStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "USE")?;
|
||||
if let Some(ref ns) = self.ns {
|
||||
write!(f, " NS {}", ns)?;
|
||||
}
|
||||
if let Some(ref db) = self.db {
|
||||
write!(f, " DB {}", db)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn yuse(i: &str) -> IResult<&str, UseStatement> {
|
||||
alt((both, ns, db))(i)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -39,32 +38,17 @@ impl PartialOrd for Subquery {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Subquery {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Subquery::Value(v) => write!(f, "({})", v),
|
||||
Subquery::Select(v) => write!(f, "({})", v),
|
||||
Subquery::Create(v) => write!(f, "({})", v),
|
||||
Subquery::Update(v) => write!(f, "({})", v),
|
||||
Subquery::Delete(v) => write!(f, "({})", v),
|
||||
Subquery::Relate(v) => write!(f, "({})", v),
|
||||
Subquery::Insert(v) => write!(f, "({})", v),
|
||||
Subquery::Ifelse(v) => write!(f, "{}", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Subquery {
|
||||
fn process(
|
||||
impl Subquery {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
Subquery::Value(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Subquery::Ifelse(ref v) => v.process(ctx, opt, exe, doc),
|
||||
Subquery::Value(ref v) => v.compute(ctx, opt, exe, doc).await,
|
||||
Subquery::Ifelse(ref v) => v.compute(ctx, opt, exe, doc).await,
|
||||
Subquery::Select(ref v) => {
|
||||
// Duplicate options
|
||||
let opt = opt.dive()?;
|
||||
|
@ -78,15 +62,17 @@ impl dbs::Process for Subquery {
|
|||
// Prepare context
|
||||
let ctx = ctx.freeze();
|
||||
// Process subquery
|
||||
let res = v.process(&ctx, &opt, exe, doc)?;
|
||||
let res = v.compute(&ctx, &opt, exe, doc).await?;
|
||||
// Process result
|
||||
match v.limit() {
|
||||
1 => match v.expr.single() {
|
||||
Some(v) => res.first(&ctx, &opt, exe).get(&ctx, &opt, exe, &v).ok(),
|
||||
None => res.first(&ctx, &opt, exe).ok(),
|
||||
Some(v) => {
|
||||
res.first(&ctx, &opt, exe).await.get(&ctx, &opt, exe, &v).await.ok()
|
||||
}
|
||||
None => res.first(&ctx, &opt, exe).await.ok(),
|
||||
},
|
||||
_ => match v.expr.single() {
|
||||
Some(v) => res.get(&ctx, &opt, exe, &v).ok(),
|
||||
Some(v) => res.get(&ctx, &opt, exe, &v).await.ok(),
|
||||
None => res.ok(),
|
||||
},
|
||||
}
|
||||
|
@ -104,7 +90,7 @@ impl dbs::Process for Subquery {
|
|||
// Prepare context
|
||||
let ctx = ctx.freeze();
|
||||
// Process subquery
|
||||
match v.process(&ctx, &opt, exe, doc)? {
|
||||
match v.compute(&ctx, &opt, exe, doc).await? {
|
||||
Value::Array(mut v) => match v.len() {
|
||||
1 => Ok(v.value.remove(0)),
|
||||
_ => Ok(v.into()),
|
||||
|
@ -125,7 +111,7 @@ impl dbs::Process for Subquery {
|
|||
// Prepare context
|
||||
let ctx = ctx.freeze();
|
||||
// Process subquery
|
||||
match v.process(&ctx, &opt, exe, doc)? {
|
||||
match v.compute(&ctx, &opt, exe, doc).await? {
|
||||
Value::Array(mut v) => match v.len() {
|
||||
1 => Ok(v.value.remove(0)),
|
||||
_ => Ok(v.into()),
|
||||
|
@ -146,7 +132,7 @@ impl dbs::Process for Subquery {
|
|||
// Prepare context
|
||||
let ctx = ctx.freeze();
|
||||
// Process subquery
|
||||
match v.process(&ctx, &opt, exe, doc)? {
|
||||
match v.compute(&ctx, &opt, exe, doc).await? {
|
||||
Value::Array(mut v) => match v.len() {
|
||||
1 => Ok(v.value.remove(0)),
|
||||
_ => Ok(v.into()),
|
||||
|
@ -167,7 +153,7 @@ impl dbs::Process for Subquery {
|
|||
// Prepare context
|
||||
let ctx = ctx.freeze();
|
||||
// Process subquery
|
||||
match v.process(&ctx, &opt, exe, doc)? {
|
||||
match v.compute(&ctx, &opt, exe, doc).await? {
|
||||
Value::Array(mut v) => match v.len() {
|
||||
1 => Ok(v.value.remove(0)),
|
||||
_ => Ok(v.into()),
|
||||
|
@ -188,7 +174,7 @@ impl dbs::Process for Subquery {
|
|||
// Prepare context
|
||||
let ctx = ctx.freeze();
|
||||
// Process subquery
|
||||
match v.process(&ctx, &opt, exe, doc)? {
|
||||
match v.compute(&ctx, &opt, exe, doc).await? {
|
||||
Value::Array(mut v) => match v.len() {
|
||||
1 => Ok(v.value.remove(0)),
|
||||
_ => Ok(v.into()),
|
||||
|
@ -200,6 +186,21 @@ impl dbs::Process for Subquery {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Subquery {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Subquery::Value(v) => write!(f, "({})", v),
|
||||
Subquery::Select(v) => write!(f, "({})", v),
|
||||
Subquery::Create(v) => write!(f, "({})", v),
|
||||
Subquery::Update(v) => write!(f, "({})", v),
|
||||
Subquery::Delete(v) => write!(f, "({})", v),
|
||||
Subquery::Relate(v) => write!(f, "({})", v),
|
||||
Subquery::Insert(v) => write!(f, "({})", v),
|
||||
Subquery::Ifelse(v) => write!(f, "{}", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subquery(i: &str) -> IResult<&str, Subquery> {
|
||||
alt((subquery_ifelse, subquery_others))(i)
|
||||
}
|
||||
|
|
|
@ -6,8 +6,14 @@ use crate::sql::idiom::Idiom;
|
|||
use crate::sql::value::Value;
|
||||
|
||||
impl Value {
|
||||
pub fn array(&mut self, ctx: &Runtime, opt: &Options, exe: &mut Executor, path: &Idiom) {
|
||||
pub async fn array(
|
||||
&mut self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
) {
|
||||
let val = Value::from(Array::default());
|
||||
self.set(ctx, opt, exe, path, Value::from(val))
|
||||
self.set(ctx, opt, exe, path, Value::from(val)).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,25 +6,37 @@ use crate::sql::number::Number;
|
|||
use crate::sql::value::Value;
|
||||
|
||||
impl Value {
|
||||
pub fn decrement(
|
||||
pub async fn decrement(
|
||||
&mut self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
val: Value,
|
||||
) {
|
||||
match self.get(ctx, opt, exe, path) {
|
||||
match self.get(ctx, opt, exe, path).await {
|
||||
Value::Number(v) => match val {
|
||||
Value::Number(x) => self.set(ctx, opt, exe, path, Value::from(v - x)),
|
||||
Value::Number(x) => {
|
||||
self.set(ctx, opt, exe, path, Value::from(v - x)).await;
|
||||
()
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
Value::Array(v) => match val {
|
||||
Value::Array(x) => self.set(ctx, opt, exe, path, Value::from(v - x)),
|
||||
x => self.set(ctx, opt, exe, path, Value::from(v - x)),
|
||||
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::None => match val {
|
||||
Value::Number(x) => self.set(ctx, opt, exe, path, Value::from(Number::from(0) - x)),
|
||||
Value::Number(x) => {
|
||||
self.set(ctx, opt, exe, path, Value::from(Number::from(0) - x)).await;
|
||||
()
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
_ => (),
|
||||
|
@ -39,53 +51,53 @@ mod tests {
|
|||
use crate::dbs::test::mock;
|
||||
use crate::sql::test::Parse;
|
||||
|
||||
#[test]
|
||||
fn dec_none() {
|
||||
#[tokio::test]
|
||||
async fn dec_none() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("other");
|
||||
let mut val = Value::parse("{ test: 100 }");
|
||||
let res = Value::parse("{ test: 100, other: -10 }");
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::from(10));
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::from(10)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dec_number() {
|
||||
#[tokio::test]
|
||||
async fn dec_number() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test");
|
||||
let mut val = Value::parse("{ test: 100 }");
|
||||
let res = Value::parse("{ test: 90 }");
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::from(10));
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::from(10)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dec_array_number() {
|
||||
#[tokio::test]
|
||||
async fn dec_array_number() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(10));
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::from(10)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dec_array_value() {
|
||||
#[tokio::test]
|
||||
async fn dec_array_value() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(200));
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::from(200)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dec_array_array() {
|
||||
#[tokio::test]
|
||||
async fn dec_array_array() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test");
|
||||
let mut val = Value::parse("{ test: [100, 200, 300] }");
|
||||
let res = Value::parse("{ test: [200] }");
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::parse("[100, 300]"));
|
||||
val.decrement(&ctx, &opt, &mut exe, &idi, Value::parse("[100, 300]")).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Process;
|
||||
use crate::dbs::Runtime;
|
||||
use crate::sql::array::Abolish;
|
||||
use crate::sql::idiom::Idiom;
|
||||
use crate::sql::part::Part;
|
||||
use crate::sql::value::Value;
|
||||
use async_recursion::async_recursion;
|
||||
use std::collections::HashMap;
|
||||
|
||||
impl Value {
|
||||
pub fn del(&mut self, ctx: &Runtime, opt: &Options, exe: &mut Executor, path: &Idiom) {
|
||||
#[async_recursion]
|
||||
pub async fn del(
|
||||
&mut self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
) {
|
||||
match path.parts.first() {
|
||||
// Get the current path part
|
||||
Some(p) => match self {
|
||||
|
@ -16,7 +25,7 @@ impl Value {
|
|||
Part::Field(p) => match path.parts.len() {
|
||||
1 => v.remove(&p.name),
|
||||
_ => match v.value.get_mut(&p.name) {
|
||||
Some(v) if v.is_some() => v.del(ctx, opt, exe, &path.next()),
|
||||
Some(v) if v.is_some() => v.del(ctx, opt, exe, &path.next()).await,
|
||||
_ => (),
|
||||
},
|
||||
},
|
||||
|
@ -26,7 +35,11 @@ impl Value {
|
|||
Value::Array(v) => match p {
|
||||
Part::All => match path.parts.len() {
|
||||
1 => v.value.clear(),
|
||||
_ => v.value.iter_mut().for_each(|v| v.del(ctx, opt, exe, &path.next())),
|
||||
_ => {
|
||||
for v in &mut v.value {
|
||||
v.del(ctx, opt, exe, &path.next()).await
|
||||
}
|
||||
}
|
||||
},
|
||||
Part::First => match path.parts.len() {
|
||||
1 => {
|
||||
|
@ -36,7 +49,7 @@ impl Value {
|
|||
}
|
||||
}
|
||||
_ => match v.value.first_mut() {
|
||||
Some(v) => v.del(ctx, opt, exe, &path.next()),
|
||||
Some(v) => v.del(ctx, opt, exe, &path.next()).await,
|
||||
None => (),
|
||||
},
|
||||
},
|
||||
|
@ -48,7 +61,7 @@ impl Value {
|
|||
}
|
||||
}
|
||||
_ => match v.value.last_mut() {
|
||||
Some(v) => v.del(ctx, opt, exe, &path.next()),
|
||||
Some(v) => v.del(ctx, opt, exe, &path.next()).await,
|
||||
None => (),
|
||||
},
|
||||
},
|
||||
|
@ -61,22 +74,32 @@ impl Value {
|
|||
}
|
||||
_ => match path.parts.len() {
|
||||
_ => match v.value.get_mut(i.to_usize()) {
|
||||
Some(v) => v.del(ctx, opt, exe, &path.next()),
|
||||
Some(v) => v.del(ctx, opt, exe, &path.next()).await,
|
||||
None => (),
|
||||
},
|
||||
},
|
||||
},
|
||||
Part::Where(w) => match path.parts.len() {
|
||||
1 => v.value.retain(|v| match w.process(ctx, opt, exe, Some(v)) {
|
||||
Ok(v) if v.is_truthy() => false,
|
||||
_ => true,
|
||||
}),
|
||||
_ => v.value.iter_mut().for_each(|v| {
|
||||
match w.process(ctx, opt, exe, Some(v)) {
|
||||
Ok(mut v) if v.is_truthy() => v.del(ctx, opt, exe, &path.next()),
|
||||
_ => (),
|
||||
1 => {
|
||||
let mut m = HashMap::new();
|
||||
for (i, v) in v.value.iter().enumerate() {
|
||||
match w.compute(ctx, opt, exe, Some(&v)).await {
|
||||
Ok(o) if o.is_truthy() => m.insert(i, ()),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
v.value.abolish(|i| m.contains_key(&i))
|
||||
}
|
||||
_ => {
|
||||
for v in &mut v.value {
|
||||
match w.compute(ctx, opt, exe, Some(&v)).await {
|
||||
Ok(o) if o.is_truthy() => {
|
||||
v.del(ctx, opt, exe, &path.next()).await
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
},
|
||||
_ => (),
|
||||
},
|
||||
|
@ -96,85 +119,105 @@ mod tests {
|
|||
use crate::dbs::test::mock;
|
||||
use crate::sql::test::Parse;
|
||||
|
||||
#[test]
|
||||
fn del_none() {
|
||||
#[tokio::test]
|
||||
async fn del_none() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom {
|
||||
parts: vec![],
|
||||
};
|
||||
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
|
||||
let res = Value::parse("{ test: { other: null, something: 123 } }");
|
||||
val.del(&ctx, &opt, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_reset() {
|
||||
#[tokio::test]
|
||||
async fn del_reset() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test");
|
||||
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
|
||||
let res = Value::parse("{ }");
|
||||
val.del(&ctx, &opt, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_basic() {
|
||||
#[tokio::test]
|
||||
async fn del_basic() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_wrong() {
|
||||
#[tokio::test]
|
||||
async fn del_wrong() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_other() {
|
||||
#[tokio::test]
|
||||
async fn del_other() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_array() {
|
||||
#[tokio::test]
|
||||
async fn del_array() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_array_field() {
|
||||
#[tokio::test]
|
||||
async fn del_array_field() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn del_array_fields() {
|
||||
#[tokio::test]
|
||||
async fn del_array_fields() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi);
|
||||
val.del(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn del_array_where_field() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn del_array_where_fields() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::sql::part::Part;
|
|||
use crate::sql::value::Value;
|
||||
|
||||
impl Value {
|
||||
pub fn first(&self, ctx: &Runtime, opt: &Options, exe: &mut Executor) -> Self {
|
||||
self.get(ctx, opt, exe, &Idiom::from(vec![Part::First]))
|
||||
pub async fn first(&self, ctx: &Runtime, opt: &Options<'_>, exe: &mut Executor) -> Self {
|
||||
self.get(ctx, opt, exe, &Idiom::from(vec![Part::First])).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,66 @@
|
|||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Process;
|
||||
use crate::dbs::Runtime;
|
||||
use crate::sql::field::{Field, Fields};
|
||||
use crate::sql::idiom::Idiom;
|
||||
use crate::sql::part::Part;
|
||||
use crate::sql::statements::select::SelectStatement;
|
||||
use crate::sql::value::{Value, Values};
|
||||
use async_recursion::async_recursion;
|
||||
|
||||
impl Value {
|
||||
pub fn get(&self, ctx: &Runtime, opt: &Options, exe: &mut Executor, path: &Idiom) -> Self {
|
||||
#[async_recursion]
|
||||
pub async fn get(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
) -> Self {
|
||||
match path.parts.first() {
|
||||
// Get the current path part
|
||||
Some(p) => match self {
|
||||
// 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()),
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
|
||||
None => Value::None,
|
||||
},
|
||||
_ => Value::None,
|
||||
},
|
||||
// Current path part is an array
|
||||
Value::Array(v) => match p {
|
||||
Part::All => v
|
||||
.value
|
||||
.iter()
|
||||
.map(|v| v.get(ctx, opt, exe, &path.next()))
|
||||
.collect::<Vec<Value>>()
|
||||
.into(),
|
||||
Part::All => {
|
||||
let mut a = Vec::new();
|
||||
for v in &v.value {
|
||||
a.push(v.get(ctx, opt, exe, &path.next()).await)
|
||||
}
|
||||
a.into()
|
||||
}
|
||||
Part::First => match v.value.first() {
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()),
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
|
||||
None => Value::None,
|
||||
},
|
||||
Part::Last => match v.value.last() {
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()),
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
|
||||
None => Value::None,
|
||||
},
|
||||
Part::Index(i) => match v.value.get(i.to_usize()) {
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()),
|
||||
Some(v) => v.get(ctx, opt, exe, &path.next()).await,
|
||||
None => Value::None,
|
||||
},
|
||||
Part::Where(w) => v
|
||||
.value
|
||||
.iter()
|
||||
.filter_map(|v| match w.process(ctx, opt, exe, Some(v)) {
|
||||
Ok(v) if v.is_truthy() => Some(v.get(ctx, opt, exe, &path.next())),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<Value>>()
|
||||
.into(),
|
||||
Part::Where(w) => {
|
||||
let mut a = Vec::new();
|
||||
for v in &v.value {
|
||||
match w.compute(ctx, opt, exe, Some(&v)).await {
|
||||
Ok(x) if x.is_truthy() => {
|
||||
a.push(v.get(ctx, opt, exe, &path.next()).await)
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
a.into()
|
||||
}
|
||||
_ => Value::None,
|
||||
},
|
||||
// Current path part is a thing
|
||||
|
@ -63,8 +74,8 @@ impl Value {
|
|||
what: Values(vec![Value::Thing(v.clone())]),
|
||||
..SelectStatement::default()
|
||||
};
|
||||
match stm.process(ctx, opt, exe, None) {
|
||||
Ok(v) => v.get(ctx, opt, exe, &path.next()),
|
||||
match stm.compute(ctx, opt, exe, None).await {
|
||||
Ok(v) => v.get(ctx, opt, exe, &path.next()).await,
|
||||
Err(_) => Value::None,
|
||||
}
|
||||
}
|
||||
|
@ -86,32 +97,32 @@ mod tests {
|
|||
use crate::sql::test::Parse;
|
||||
use crate::sql::thing::Thing;
|
||||
|
||||
#[test]
|
||||
fn get_none() {
|
||||
#[tokio::test]
|
||||
async fn get_none() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom {
|
||||
parts: vec![],
|
||||
};
|
||||
let val = Value::parse("{ test: { other: null, something: 123 } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_basic() {
|
||||
#[tokio::test]
|
||||
async fn get_basic() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test.something");
|
||||
let val = Value::parse("{ test: { other: null, something: 123 } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, Value::from(123));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_thing() {
|
||||
#[tokio::test]
|
||||
async fn get_thing() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test.other");
|
||||
let val = Value::parse("{ test: { other: test:tobie, something: 123 } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(
|
||||
res,
|
||||
Value::from(Thing {
|
||||
|
@ -121,21 +132,21 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_array() {
|
||||
#[tokio::test]
|
||||
async fn get_array() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test.something[1]");
|
||||
let val = Value::parse("{ test: { something: [123, 456, 789] } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, Value::from(456));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_array_thing() {
|
||||
#[tokio::test]
|
||||
async fn get_array_thing() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test.something[1]");
|
||||
let val = Value::parse("{ test: { something: [test:tobie, test:jaime] } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(
|
||||
res,
|
||||
Value::from(Thing {
|
||||
|
@ -145,21 +156,44 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_array_field() {
|
||||
#[tokio::test]
|
||||
async fn get_array_field() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test.something[1].age");
|
||||
let val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, Value::from(36));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_array_fields() {
|
||||
#[tokio::test]
|
||||
async fn get_array_fields() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test.something[*].age");
|
||||
let val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi);
|
||||
let res = val.get(&ctx, &opt, &mut exe, &idi).await;
|
||||
assert_eq!(res, Value::from(vec![34, 36]));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_array_where_field() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi).await;
|
||||
assert_eq!(res, Value::from(vec![36]));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_array_where_fields() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi).await;
|
||||
assert_eq!(
|
||||
res,
|
||||
Value::from(vec![Value::from(map! {
|
||||
"age".to_string() => Value::from(36),
|
||||
})])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,27 +6,45 @@ use crate::sql::number::Number;
|
|||
use crate::sql::value::Value;
|
||||
|
||||
impl Value {
|
||||
pub fn increment(
|
||||
pub async fn increment(
|
||||
&mut self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
val: Value,
|
||||
) {
|
||||
match self.get(ctx, opt, exe, path) {
|
||||
match self.get(ctx, opt, exe, path).await {
|
||||
Value::Number(v) => match val {
|
||||
Value::Number(x) => self.set(ctx, opt, exe, path, Value::from(v + x)),
|
||||
Value::Number(x) => {
|
||||
self.set(ctx, opt, exe, path, Value::from(v + x)).await;
|
||||
()
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
Value::Array(v) => match val {
|
||||
Value::Array(x) => self.set(ctx, opt, exe, path, Value::from(v + x)),
|
||||
x => self.set(ctx, opt, exe, path, Value::from(v + x)),
|
||||
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::None => match val {
|
||||
Value::Number(x) => self.set(ctx, opt, exe, path, Value::from(Number::from(0) + x)),
|
||||
Value::Array(x) => self.set(ctx, opt, exe, path, Value::from(x)),
|
||||
x => self.set(ctx, opt, exe, path, Value::from(vec![x])),
|
||||
Value::Number(x) => {
|
||||
self.set(ctx, opt, exe, 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;
|
||||
()
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
@ -40,53 +58,53 @@ mod tests {
|
|||
use crate::dbs::test::mock;
|
||||
use crate::sql::test::Parse;
|
||||
|
||||
#[test]
|
||||
fn inc_none() {
|
||||
#[tokio::test]
|
||||
async fn inc_none() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("other");
|
||||
let mut val = Value::parse("{ test: 100 }");
|
||||
let res = Value::parse("{ test: 100, other: +10 }");
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::from(10));
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::from(10)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inc_number() {
|
||||
#[tokio::test]
|
||||
async fn inc_number() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom::parse("test");
|
||||
let mut val = Value::parse("{ test: 100 }");
|
||||
let res = Value::parse("{ test: 110 }");
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::from(10));
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::from(10)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inc_array_number() {
|
||||
#[tokio::test]
|
||||
async fn inc_array_number() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(10));
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::from(10)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inc_array_value() {
|
||||
#[tokio::test]
|
||||
async fn inc_array_value() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(200));
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::from(200)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inc_array_array() {
|
||||
#[tokio::test]
|
||||
async fn inc_array_array() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::parse("[100, 300, 400, 500]"));
|
||||
val.increment(&ctx, &opt, &mut exe, &idi, Value::parse("[100, 300, 400, 500]")).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::sql::part::Part;
|
|||
use crate::sql::value::Value;
|
||||
|
||||
impl Value {
|
||||
pub fn last(&self, ctx: &Runtime, opt: &Options, exe: &mut Executor) -> Self {
|
||||
self.get(ctx, opt, exe, &Idiom::from(vec![Part::Last]))
|
||||
pub async fn last(&self, ctx: &Runtime, opt: &Options<'_>, exe: &mut Executor) -> Self {
|
||||
self.get(ctx, opt, exe, &Idiom::from(vec![Part::Last])).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,14 @@ use crate::sql::object::Object;
|
|||
use crate::sql::value::Value;
|
||||
|
||||
impl Value {
|
||||
pub fn object(&mut self, ctx: &Runtime, opt: &Options, exe: &mut Executor, path: &Idiom) {
|
||||
pub async fn object(
|
||||
&mut self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
) {
|
||||
let val = Value::from(Object::default());
|
||||
self.set(ctx, opt, exe, path, val)
|
||||
self.set(ctx, opt, exe, path, val).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Process;
|
||||
use crate::dbs::Runtime;
|
||||
use crate::sql::idiom::Idiom;
|
||||
use crate::sql::object::Object;
|
||||
use crate::sql::part::Part;
|
||||
use crate::sql::value::Value;
|
||||
use async_recursion::async_recursion;
|
||||
|
||||
impl Value {
|
||||
pub fn set(
|
||||
#[async_recursion]
|
||||
pub async fn set(
|
||||
&mut self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
path: &Idiom,
|
||||
val: Value,
|
||||
|
@ -22,10 +23,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),
|
||||
Some(v) if v.is_some() => v.set(ctx, opt, exe, &path.next(), val).await,
|
||||
_ => {
|
||||
let mut obj = Value::from(Object::default());
|
||||
obj.set(ctx, opt, exe, &path.next(), val);
|
||||
obj.set(ctx, opt, exe, &path.next(), val).await;
|
||||
v.insert(&p.name, obj)
|
||||
}
|
||||
},
|
||||
|
@ -33,29 +34,32 @@ impl Value {
|
|||
},
|
||||
// Current path part is an array
|
||||
Value::Array(v) => match p {
|
||||
Part::All => v
|
||||
.value
|
||||
.iter_mut()
|
||||
.for_each(|v| v.set(ctx, opt, exe, &path.next(), val.clone())),
|
||||
Part::All => {
|
||||
for v in &mut v.value {
|
||||
v.set(ctx, opt, exe, &path.next(), val.clone()).await
|
||||
}
|
||||
}
|
||||
Part::First => match v.value.first_mut() {
|
||||
Some(v) => v.set(ctx, opt, exe, &path.next(), val),
|
||||
Some(v) => v.set(ctx, opt, exe, &path.next(), val).await,
|
||||
None => (),
|
||||
},
|
||||
Part::Last => match v.value.last_mut() {
|
||||
Some(v) => v.set(ctx, opt, exe, &path.next(), val),
|
||||
Some(v) => v.set(ctx, opt, exe, &path.next(), val).await,
|
||||
None => (),
|
||||
},
|
||||
Part::Index(i) => match v.value.get_mut(i.to_usize()) {
|
||||
Some(v) => v.set(ctx, opt, exe, &path.next(), val),
|
||||
Some(v) => v.set(ctx, opt, exe, &path.next(), val).await,
|
||||
None => (),
|
||||
},
|
||||
Part::Where(w) => {
|
||||
v.value.iter_mut().for_each(|v| match w.process(ctx, opt, exe, Some(v)) {
|
||||
Ok(mut v) if v.is_truthy() => {
|
||||
v.set(ctx, opt, exe, &path.next(), val.clone())
|
||||
for v in &mut v.value {
|
||||
match w.compute(ctx, opt, exe, Some(&v)).await {
|
||||
Ok(x) if x.is_truthy() => {
|
||||
v.set(ctx, opt, exe, &path.next(), val.clone()).await
|
||||
}
|
||||
_ => (),
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
|
@ -75,85 +79,105 @@ mod tests {
|
|||
use crate::dbs::test::mock;
|
||||
use crate::sql::test::Parse;
|
||||
|
||||
#[test]
|
||||
fn set_none() {
|
||||
#[tokio::test]
|
||||
async fn set_none() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
let idi = Idiom {
|
||||
parts: vec![],
|
||||
};
|
||||
let mut val = Value::parse("{ test: { other: null, something: 123 } }");
|
||||
let res = Value::parse("999");
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_reset() {
|
||||
#[tokio::test]
|
||||
async fn set_reset() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(999));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_basic() {
|
||||
#[tokio::test]
|
||||
async fn set_basic() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(999));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_wrong() {
|
||||
#[tokio::test]
|
||||
async fn set_wrong() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(999));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_other() {
|
||||
#[tokio::test]
|
||||
async fn set_other() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(999));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_array() {
|
||||
#[tokio::test]
|
||||
async fn set_array() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(999));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(999)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_array_field() {
|
||||
#[tokio::test]
|
||||
async fn set_array_field() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(21));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(21)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_array_fields() {
|
||||
#[tokio::test]
|
||||
async fn set_array_fields() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(21));
|
||||
val.set(&ctx, &opt, &mut exe, &idi, Value::from(21)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn set_array_where_field() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(21)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn set_array_where_fields() {
|
||||
let (ctx, opt, mut exe) = mock();
|
||||
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, &mut exe, &idi, Value::from(21)).await;
|
||||
assert_eq!(res, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::dbs;
|
||||
use crate::dbs::Executor;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Runtime;
|
||||
|
@ -21,6 +20,7 @@ use crate::sql::strand::{strand, Strand};
|
|||
use crate::sql::subquery::{subquery, Subquery};
|
||||
use crate::sql::table::{table, Table};
|
||||
use crate::sql::thing::{thing, Thing};
|
||||
use async_recursion::async_recursion;
|
||||
use chrono::{DateTime, Utc};
|
||||
use dec::Decimal;
|
||||
use fuzzy_matcher::skim::SkimMatcherV2;
|
||||
|
@ -762,13 +762,14 @@ impl fmt::Display for Value {
|
|||
}
|
||||
}
|
||||
|
||||
impl dbs::Process for Value {
|
||||
fn process(
|
||||
impl Value {
|
||||
#[async_recursion]
|
||||
pub async fn compute(
|
||||
&self,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
opt: &Options<'_>,
|
||||
exe: &mut Executor,
|
||||
doc: Option<&Value>,
|
||||
doc: Option<&'async_recursion Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
Value::None => Ok(Value::None),
|
||||
|
@ -776,13 +777,13 @@ impl dbs::Process for Value {
|
|||
Value::Null => Ok(Value::Null),
|
||||
Value::True => Ok(Value::True),
|
||||
Value::False => Ok(Value::False),
|
||||
Value::Param(v) => v.process(ctx, opt, exe, doc),
|
||||
Value::Idiom(v) => v.process(ctx, opt, exe, doc),
|
||||
Value::Array(v) => v.process(ctx, opt, exe, doc),
|
||||
Value::Object(v) => v.process(ctx, opt, exe, doc),
|
||||
Value::Function(v) => v.process(ctx, opt, exe, doc),
|
||||
Value::Subquery(v) => v.process(ctx, opt, exe, doc),
|
||||
Value::Expression(v) => v.process(ctx, opt, exe, doc),
|
||||
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,
|
||||
_ => Ok(self.to_owned()),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue