surrealpatch/src/sql/expression.rs

175 lines
4.7 KiB
Rust
Raw Normal View History

2021-03-29 15:43:37 +00:00
use crate::dbs::Executor;
use crate::dbs::Options;
use crate::dbs::Runtime;
2021-03-29 15:43:37 +00:00
use crate::err::Error;
use crate::fnc;
2020-06-29 15:36:01 +00:00
use crate::sql::operator::{operator, Operator};
use crate::sql::value::{single, value, Value};
2020-06-29 15:36:01 +00:00
use nom::IResult;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str;
2021-03-29 15:43:37 +00:00
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Expression {
l: Value,
o: Operator,
r: Value,
2021-03-29 15:43:37 +00:00
}
impl Default for Expression {
fn default() -> Expression {
Expression {
l: Value::Null,
o: Operator::default(),
r: Value::Null,
}
2020-06-29 15:36:01 +00:00
}
}
2022-01-14 08:12:56 +00:00
impl Expression {
pub async fn compute(
2021-03-29 15:43:37 +00:00
&self,
ctx: &Runtime,
2022-01-14 08:12:56 +00:00
opt: &Options<'_>,
exe: &mut Executor,
doc: Option<&Value>,
) -> Result<Value, Error> {
2022-01-14 08:12:56 +00:00
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
_ => {} // Continue
},
Operator::And => match l.is_truthy() {
false => return Ok(l), // No need to continue
_ => {} // Continue
},
_ => {} // Continue
}
2022-01-14 08:12:56 +00:00
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),
Operator::Add => fnc::operate::add(l, r),
Operator::Sub => fnc::operate::sub(l, r),
Operator::Mul => fnc::operate::mul(l, r),
Operator::Div => fnc::operate::div(l, r),
Operator::Equal => fnc::operate::equal(&l, &r),
Operator::Exact => fnc::operate::exact(&l, &r),
Operator::NotEqual => fnc::operate::not_equal(&l, &r),
Operator::AllEqual => fnc::operate::all_equal(&l, &r),
Operator::AnyEqual => fnc::operate::any_equal(&l, &r),
Operator::Like => fnc::operate::like(&l, &r),
Operator::NotLike => fnc::operate::not_like(&l, &r),
Operator::AllLike => fnc::operate::all_like(&l, &r),
Operator::AnyLike => fnc::operate::any_like(&l, &r),
Operator::LessThan => fnc::operate::less_than(&l, &r),
Operator::LessThanOrEqual => fnc::operate::less_than_or_equal(&l, &r),
Operator::MoreThan => fnc::operate::more_than(&l, &r),
Operator::MoreThanOrEqual => fnc::operate::more_than_or_equal(&l, &r),
Operator::Contain => fnc::operate::contain(&l, &r),
Operator::NotContain => fnc::operate::not_contain(&l, &r),
Operator::ContainAll => fnc::operate::contain_all(&l, &r),
Operator::ContainAny => fnc::operate::contain_any(&l, &r),
Operator::ContainNone => fnc::operate::contain_none(&l, &r),
Operator::Inside => fnc::operate::inside(&l, &r),
Operator::NotInside => fnc::operate::not_inside(&l, &r),
Operator::AllInside => fnc::operate::inside_all(&l, &r),
Operator::AnyInside => fnc::operate::inside_any(&l, &r),
Operator::NoneInside => fnc::operate::inside_none(&l, &r),
Operator::Intersects => fnc::operate::intersects(&l, &r),
_ => unreachable!(),
2020-06-29 15:36:01 +00:00
}
}
}
2022-01-14 08:12:56 +00:00
impl fmt::Display for Expression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {} {}", self.l, self.o, self.r)
}
}
2020-06-29 15:36:01 +00:00
pub fn expression(i: &str) -> IResult<&str, Expression> {
let (i, l) = single(i)?;
2020-06-29 15:36:01 +00:00
let (i, o) = operator(i)?;
let (i, r) = value(i)?;
Ok((
i,
Expression {
l,
o,
r,
},
))
2020-06-29 15:36:01 +00:00
}
2021-03-29 15:43:37 +00:00
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn expression_statement() {
2021-03-29 15:43:37 +00:00
let sql = "true AND false";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("true AND false", format!("{}", out));
}
#[test]
fn expression_left_opened() {
let sql = "3 * 3 * 3 = 27";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("3 * 3 * 3 = 27", format!("{}", out));
}
#[test]
fn expression_left_closed() {
let sql = "(3 * 3 * 3) = 27";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("(3 * 3 * 3) = 27", format!("{}", out));
}
#[test]
fn expression_right_opened() {
let sql = "27 = 3 * 3 * 3";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("27 = 3 * 3 * 3", format!("{}", out));
}
#[test]
fn expression_right_closed() {
let sql = "27 = (3 * 3 * 3)";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("27 = (3 * 3 * 3)", format!("{}", out));
}
2021-03-29 15:43:37 +00:00
#[test]
fn expression_both_opened() {
let sql = "3 * 3 * 3 = 3 * 3 * 3";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("3 * 3 * 3 = 3 * 3 * 3", format!("{}", out));
}
#[test]
fn expression_both_closed() {
let sql = "(3 * 3 * 3) = (3 * 3 * 3)";
let res = expression(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("(3 * 3 * 3) = (3 * 3 * 3)", format!("{}", out));
}
2020-06-29 15:36:01 +00:00
}