1use std::collections::HashMap;
4
5#[derive(Clone, Debug)]
7pub enum QueryValue {
8 Null,
9 Integer(i64),
10 Float(f64),
11 Text(String),
12 Blob(Vec<u8>),
13}
14
15#[derive(Debug, Clone)]
17pub struct GqlQuery {
18 pub pattern: MatchPattern,
19 pub where_clause: WhereExpr,
20 pub return_items: Vec<ReturnItem>,
21 pub limit: Option<usize>,
22}
23
24#[derive(Debug, Clone)]
26pub enum WhereExpr {
27 And(Box<WhereExpr>, Box<WhereExpr>),
29 Or(Box<WhereExpr>, Box<WhereExpr>),
31 Condition(Condition),
33 True,
35}
36
37impl WhereExpr {
38 pub fn conditions(&self) -> impl Iterator<Item = &Condition> {
40 let mut stack = vec![self];
41 let mut out: Vec<&Condition> = Vec::new();
42 while let Some(expr) = stack.pop() {
43 match expr {
44 WhereExpr::Condition(c) => out.push(c),
45 WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
46 stack.push(r);
47 stack.push(l);
48 }
49 WhereExpr::True => {}
50 }
51 }
52 out.into_iter()
53 }
54
55 pub fn for_each_condition_mut(&mut self, f: &mut impl FnMut(&mut Condition)) {
57 match self {
58 WhereExpr::Condition(c) => f(c),
59 WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
60 l.for_each_condition_mut(f);
61 r.for_each_condition_mut(f);
62 }
63 WhereExpr::True => {}
64 }
65 }
66
67 pub fn is_true(&self) -> bool {
69 matches!(self, WhereExpr::True)
70 }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
75pub enum ReturnItem {
76 Variable(String),
77 Property(String, String),
78}
79
80impl ReturnItem {
81 pub fn variable(&self) -> &str {
83 match self {
84 Self::Variable(v) | Self::Property(v, _) => v,
85 }
86 }
87}
88
89#[derive(Debug, Clone)]
91pub struct MatchPattern {
92 pub elements: Vec<PatternElement>,
93}
94
95impl MatchPattern {
96 pub fn nodes(&self) -> impl Iterator<Item = &NodePattern> {
98 self.elements.iter().filter_map(|e| match e {
99 PatternElement::Node(n) => Some(n),
100 _ => None,
101 })
102 }
103
104 pub fn edges(&self) -> impl Iterator<Item = &EdgePattern> {
106 self.elements.iter().filter_map(|e| match e {
107 PatternElement::Edge(e) => Some(e),
108 _ => None,
109 })
110 }
111
112 pub fn has_variable_length(&self) -> bool {
113 self.edges().any(|e| e.max_hops > 1)
114 }
115}
116
117#[derive(Debug, Clone)]
119pub enum PatternElement {
120 Node(NodePattern),
121 Edge(EdgePattern),
122}
123
124#[derive(Debug, Clone)]
126pub struct NodePattern {
127 pub variable: Option<String>,
128 pub kind: Option<String>,
129 pub entity_type: Option<String>,
132 pub properties: HashMap<String, String>,
133}
134
135#[derive(Debug, Clone)]
137pub struct EdgePattern {
138 pub variable: Option<String>,
139 pub relations: Vec<String>,
140 pub direction: EdgeDirection,
141 pub min_hops: usize,
142 pub max_hops: usize,
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq)]
147pub enum EdgeDirection {
148 Out,
150 In,
152 Both,
154}
155
156#[derive(Debug, Clone)]
158pub struct Condition {
159 pub variable: String,
160 pub property: String,
161 pub op: CompareOp,
162 pub value: ConditionValue,
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq)]
167pub enum CompareOp {
168 Eq,
169 Neq,
170 Gt,
171 Lt,
172 Gte,
173 Lte,
174 Like,
175}
176
177#[derive(Debug, Clone)]
179pub enum ConditionValue {
180 String(String),
181 Number(f64),
182 Bool(bool),
183}