add not queries into uplang
somewhat awkwardly implemented as multiqueries, but heyfeat/vaults
parent
2d1a3b9ba7
commit
8e71e34a09
|
@ -2,7 +2,7 @@ use crate::addressing::Address;
|
|||
use crate::database::entry::EntryValue;
|
||||
use crate::database::inner::schema::data;
|
||||
use anyhow::{anyhow, Result};
|
||||
use diesel::expression::operators::{And, Or};
|
||||
use diesel::expression::operators::{And, Not, Or};
|
||||
use diesel::sql_types::Bool;
|
||||
use diesel::sqlite::Sqlite;
|
||||
use diesel::{BoxableExpression, ExpressionMethods, IntoSql, TextExpressionMethods};
|
||||
|
@ -39,6 +39,7 @@ pub enum QueryPart {
|
|||
pub enum QueryQualifier {
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -178,12 +179,12 @@ impl TryFrom<&lexpr::Value> for Query {
|
|||
"and" | "or" => {
|
||||
let (cons_vec, _) = value.clone().into_vec();
|
||||
let sub_expressions = &cons_vec[1..];
|
||||
let values: Result<Vec<Box<Query>>> = sub_expressions
|
||||
let values = sub_expressions
|
||||
.iter()
|
||||
.map(|value| Ok(Box::new(Query::try_from(value)?)))
|
||||
.collect();
|
||||
.collect::<Result<Vec<Box<Query>>>>()?;
|
||||
|
||||
if let Some(queries) = NonEmpty::from_vec(values?) {
|
||||
if let Some(queries) = NonEmpty::from_vec(values) {
|
||||
Ok(Query::MultiQuery(MultiQuery {
|
||||
qualifier: match symbol.borrow() {
|
||||
"and" => QueryQualifier::And,
|
||||
|
@ -197,6 +198,25 @@ impl TryFrom<&lexpr::Value> for Query {
|
|||
))
|
||||
}
|
||||
}
|
||||
"not" => {
|
||||
let (cons_vec, _) = value.clone().into_vec();
|
||||
let sub_expressions = &cons_vec[1..];
|
||||
let values = sub_expressions
|
||||
.iter()
|
||||
.map(|value| Ok(Box::new(Query::try_from(value)?)))
|
||||
.collect::<Result<Vec<Box<Query>>>>()?;
|
||||
|
||||
if values.len() == 1 {
|
||||
Ok(Query::MultiQuery(MultiQuery {
|
||||
qualifier: QueryQualifier::Not,
|
||||
queries: NonEmpty::from_vec(values).unwrap(),
|
||||
}))
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"Malformed expression: NOT takes exactly one parameter."
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow!(format!(
|
||||
"Malformed expression: Unknown symbol '{}'.",
|
||||
symbol
|
||||
|
@ -287,7 +307,13 @@ impl Query {
|
|||
let mut subqueries: Vec<Box<Predicate>> = subqueries?;
|
||||
match subqueries.len() {
|
||||
0 => Ok(Box::new(true.into_sql::<Bool>())),
|
||||
1 => Ok(subqueries.remove(0)),
|
||||
1 => {
|
||||
if let QueryQualifier::Not = mq.qualifier {
|
||||
Ok(Box::new(Not::new(subqueries.remove(0))))
|
||||
} else {
|
||||
Ok(subqueries.remove(0))
|
||||
}
|
||||
}
|
||||
_ => match mq.qualifier {
|
||||
QueryQualifier::And => {
|
||||
let mut result: Box<And<Box<Predicate>, Box<Predicate>>> =
|
||||
|
@ -305,6 +331,7 @@ impl Query {
|
|||
}
|
||||
Ok(Box::new(result))
|
||||
}
|
||||
QueryQualifier::Not => Err(anyhow!("NOT only takes one subquery.")),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue