use std::collections::HashMap;
#[derive(Clone, Debug)]
pub enum QueryValue {
Null,
Integer(i64),
Float(f64),
Text(String),
Blob(Vec<u8>),
}
#[derive(Debug, Clone)]
pub struct GqlQuery {
pub pattern: MatchPattern,
pub where_clause: WhereExpr,
pub return_items: Vec<ReturnItem>,
pub limit: Option<usize>,
}
#[derive(Debug, Clone)]
pub enum WhereExpr {
And(Box<WhereExpr>, Box<WhereExpr>),
Or(Box<WhereExpr>, Box<WhereExpr>),
Condition(Condition),
True,
}
impl WhereExpr {
pub fn conditions(&self) -> impl Iterator<Item = &Condition> {
let mut stack = vec![self];
let mut out: Vec<&Condition> = Vec::new();
while let Some(expr) = stack.pop() {
match expr {
WhereExpr::Condition(c) => out.push(c),
WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
stack.push(r);
stack.push(l);
}
WhereExpr::True => {}
}
}
out.into_iter()
}
pub fn for_each_condition_mut(&mut self, f: &mut impl FnMut(&mut Condition)) {
match self {
WhereExpr::Condition(c) => f(c),
WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
l.for_each_condition_mut(f);
r.for_each_condition_mut(f);
}
WhereExpr::True => {}
}
}
pub fn is_true(&self) -> bool {
matches!(self, WhereExpr::True)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ReturnItem {
Variable(String),
Property(String, String),
}
impl ReturnItem {
pub fn variable(&self) -> &str {
match self {
Self::Variable(v) | Self::Property(v, _) => v,
}
}
}
#[derive(Debug, Clone)]
pub struct MatchPattern {
pub elements: Vec<PatternElement>,
}
impl MatchPattern {
pub fn nodes(&self) -> impl Iterator<Item = &NodePattern> {
self.elements.iter().filter_map(|e| match e {
PatternElement::Node(n) => Some(n),
_ => None,
})
}
pub fn edges(&self) -> impl Iterator<Item = &EdgePattern> {
self.elements.iter().filter_map(|e| match e {
PatternElement::Edge(e) => Some(e),
_ => None,
})
}
pub fn has_variable_length(&self) -> bool {
self.edges().any(|e| e.max_hops > 1)
}
}
#[derive(Debug, Clone)]
pub enum PatternElement {
Node(NodePattern),
Edge(EdgePattern),
}
#[derive(Debug, Clone)]
pub struct NodePattern {
pub variable: Option<String>,
pub kind: Option<String>,
pub entity_type: Option<String>,
pub properties: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct EdgePattern {
pub variable: Option<String>,
pub relations: Vec<String>,
pub direction: EdgeDirection,
pub min_hops: usize,
pub max_hops: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EdgeDirection {
Out,
In,
Both,
}
#[derive(Debug, Clone)]
pub struct Condition {
pub variable: String,
pub property: String,
pub op: CompareOp,
pub value: ConditionValue,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompareOp {
Eq,
Neq,
Gt,
Lt,
Gte,
Lte,
Like,
}
#[derive(Debug, Clone)]
pub enum ConditionValue {
String(String),
Number(f64),
Bool(bool),
}