real_time_sqlx/
queries.rs1use serialize::{Condition, Constraint, ConstraintValue, FinalType, Operator, QueryTree};
4
5use crate::{
6 operations::serialize::JsonObject,
7 utils::{sql_ilike, sql_like},
8};
9
10pub mod display;
11pub mod serialize;
12
13impl FinalType {
19 pub fn compare(&self, other: &FinalType, operator: &Operator) -> bool {
21 match operator {
22 Operator::Equal => self.equals(other),
23 Operator::LessThan => self.less_than(other),
24 Operator::GreaterThan => self.greater_than(other),
25 Operator::LessThanOrEqual => self.less_than_or_equal(other),
26 Operator::GreaterThanOrEqual => self.greater_than_or_equal(other),
27 Operator::NotEqual => !self.equals(other),
28 Operator::Like => match (self, other) {
29 (FinalType::String(s), FinalType::String(t)) => sql_like(t, s),
30 _ => false,
31 },
32 Operator::ILike => match (self, other) {
33 (FinalType::String(s), FinalType::String(t)) => sql_ilike(t, s),
34 _ => false,
35 },
36 _ => panic!("Invalid operator {} for comparison", operator),
37 }
38 }
39
40 pub fn equals(&self, other: &FinalType) -> bool {
44 match (self, other) {
45 (FinalType::Number(n), FinalType::Number(m)) => {
46 if n.is_f64() && m.is_f64() {
47 n.as_f64().unwrap() == m.as_f64().unwrap()
48 } else if n.is_i64() && m.is_i64() {
49 n.as_i64().unwrap() == m.as_i64().unwrap()
50 } else {
51 false
52 }
53 }
54 (FinalType::String(s), FinalType::String(t)) => s == t,
55 (FinalType::Bool(b), FinalType::Bool(c)) => b == c,
56 (FinalType::Null, FinalType::Null) => true,
57 _ => false,
58 }
59 }
60
61 pub fn less_than(&self, other: &FinalType) -> bool {
63 match (self, other) {
64 (FinalType::Number(n), FinalType::Number(m)) => {
65 if n.is_f64() && m.is_f64() {
66 n.as_f64().unwrap() < m.as_f64().unwrap()
67 } else if n.is_i64() && m.is_i64() {
68 n.as_i64().unwrap() < m.as_i64().unwrap()
69 } else {
70 false
71 }
72 }
73 (FinalType::String(s), FinalType::String(t)) => s < t,
74 (FinalType::Bool(b), FinalType::Bool(c)) => b < c,
75 _ => false,
76 }
77 }
78
79 pub fn greater_than(&self, other: &FinalType) -> bool {
81 match (self, other) {
82 (FinalType::Number(n), FinalType::Number(m)) => {
83 if n.is_f64() && m.is_f64() {
84 n.as_f64().unwrap() > m.as_f64().unwrap()
85 } else if n.is_i64() && m.is_i64() {
86 n.as_i64().unwrap() > m.as_i64().unwrap()
87 } else {
88 false
89 }
90 }
91 (FinalType::String(s), FinalType::String(t)) => s > t,
92 (FinalType::Bool(b), FinalType::Bool(c)) => b > c,
93 _ => false,
94 }
95 }
96
97 pub fn less_than_or_equal(&self, other: &FinalType) -> bool {
99 self.less_than(other) || self.equals(other)
100 }
101
102 pub fn greater_than_or_equal(&self, other: &FinalType) -> bool {
104 self.greater_than(other) || self.equals(other)
105 }
106}
107
108impl ConstraintValue {
109 pub fn compare(&self, other: &FinalType, operator: &Operator) -> bool {
113 match self {
114 ConstraintValue::Final(final_type) => final_type.compare(other, operator),
115 ConstraintValue::List(list) => match operator {
116 Operator::In => {
117 for value in list {
118 if value.compare(other, &Operator::Equal) {
119 return true;
120 }
121 }
122 false
123 }
124 _ => panic!("Invalid operator {} for list comparison", operator),
125 },
126 }
127 }
128}
129
130pub trait Checkable {
135 fn check(&self, object: &JsonObject) -> bool;
136}
137
138impl Checkable for Constraint {
139 fn check(&self, object: &JsonObject) -> bool {
141 let value = object
142 .get(&self.column)
143 .expect("Column not found in JSON object");
144
145 let final_type = FinalType::try_from(value.clone())
146 .expect(format!("Incompatible value for column: {value}").as_str());
147
148 self.value.compare(&final_type, &self.operator)
149 }
150}
151
152impl Checkable for Condition {
153 fn check(&self, object: &JsonObject) -> bool {
155 match self {
156 Condition::Single { constraint } => constraint.check(object),
157 Condition::And { conditions } => {
158 for condition in conditions {
159 if !condition.check(object) {
160 return false;
161 }
162 }
163 true
164 }
165 Condition::Or { conditions } => {
166 for condition in conditions {
167 if condition.check(object) {
168 return true;
169 }
170 }
171 false
172 }
173 }
174 }
175}
176
177impl Checkable for QueryTree {
178 fn check(&self, object: &JsonObject) -> bool {
180 if let Some(condition) = &self.condition {
181 condition.check(object)
182 } else {
183 true
184 }
185 }
186}