Skip to main content

acts_next/store/
query.rs

1use serde::Serialize;
2use serde_json::{Value, json};
3use std::{collections::HashSet, slice::IterMut};
4
5#[derive(Debug, Clone)]
6pub struct Query {
7    offset: usize,
8    limit: usize,
9    conds: Vec<Cond>,
10    order_by: Vec<(String, bool)>,
11}
12
13#[derive(Debug, Clone)]
14pub enum CondType {
15    And,
16    Or,
17}
18
19#[derive(Debug, Clone)]
20pub struct Cond {
21    pub r#type: CondType,
22    pub conds: Vec<Expr>,
23    pub result: HashSet<Box<[u8]>>,
24}
25
26#[derive(Debug, Clone, PartialEq)]
27pub enum ExprOp {
28    /// equal
29    EQ,
30
31    /// not equal
32    NE,
33
34    /// less than
35    LT,
36
37    /// less and equal
38    LE,
39
40    /// greater then
41    GT,
42
43    /// greater and equal
44    GE,
45}
46
47#[derive(Debug, Clone)]
48pub struct Expr {
49    pub op: ExprOp,
50    pub key: String,
51    pub value: Value,
52}
53
54impl Expr {
55    pub fn key(&self) -> &str {
56        &self.key
57    }
58    pub fn value(&self) -> &Value {
59        &self.value
60    }
61
62    pub fn eq<T: Serialize>(key: &str, v: T) -> Self {
63        Self {
64            op: ExprOp::EQ,
65            key: key.to_string(),
66            value: json!(v),
67        }
68    }
69
70    pub fn ne<T: Serialize>(key: &str, v: T) -> Self {
71        Self {
72            op: ExprOp::NE,
73            key: key.to_string(),
74            value: json!(v),
75        }
76    }
77
78    pub fn gt<T: Serialize>(key: &str, v: T) -> Self {
79        Self {
80            op: ExprOp::GT,
81            key: key.to_string(),
82            value: json!(v),
83        }
84    }
85
86    pub fn lt<T: Serialize>(key: &str, v: T) -> Self {
87        Self {
88            op: ExprOp::LT,
89            key: key.to_string(),
90            value: json!(v),
91        }
92    }
93
94    pub fn le<T: Serialize>(key: &str, v: T) -> Self {
95        Self {
96            op: ExprOp::LE,
97            key: key.to_string(),
98            value: json!(v),
99        }
100    }
101
102    pub fn ge<T: Serialize>(key: &str, v: T) -> Self {
103        Self {
104            op: ExprOp::GE,
105            key: key.to_string(),
106            value: json!(v),
107        }
108    }
109}
110
111impl Cond {
112    pub fn or() -> Self {
113        Self {
114            r#type: CondType::Or,
115            conds: Default::default(),
116            result: HashSet::new(),
117        }
118    }
119
120    pub fn and() -> Self {
121        Self {
122            r#type: CondType::And,
123            conds: Default::default(),
124            result: HashSet::new(),
125        }
126    }
127
128    pub fn conds(&self) -> &Vec<Expr> {
129        &self.conds
130    }
131
132    pub fn push(mut self, expr: Expr) -> Self {
133        self.conds.push(expr);
134        self
135    }
136}
137
138impl Default for Query {
139    fn default() -> Self {
140        Self::new()
141    }
142}
143
144impl Query {
145    pub fn new() -> Self {
146        Query {
147            offset: 0,
148            limit: 100000, // default to a big number
149            order_by: Vec::new(),
150            conds: Vec::new(),
151        }
152    }
153
154    pub fn queries_mut(&mut self) -> IterMut<'_, Cond> {
155        self.conds.iter_mut()
156    }
157
158    pub fn queries(&mut self) -> &Vec<Cond> {
159        &self.conds
160    }
161
162    pub fn calc(&self) -> HashSet<Box<[u8]>> {
163        let mut result = HashSet::new();
164        for cond in self.conds.iter() {
165            if result.is_empty() {
166                result = cond.result.clone();
167            } else {
168                result = result
169                    .intersection(&cond.result)
170                    .cloned()
171                    .collect::<HashSet<_>>()
172            }
173        }
174        result
175    }
176
177    pub fn push(mut self, cond: Cond) -> Self {
178        self.conds.push(cond);
179
180        self
181    }
182
183    pub fn set_offset(mut self, offset: usize) -> Self {
184        self.offset = offset;
185
186        self
187    }
188
189    pub fn set_limit(mut self, limit: usize) -> Self {
190        self.limit = limit;
191
192        self
193    }
194
195    pub fn set_order(mut self, order_by: &[(String, bool)]) -> Self {
196        self.order_by = order_by.to_vec();
197
198        self
199    }
200
201    pub fn push_order(mut self, order: &str, is_rev: bool) -> Self {
202        self.order_by.push((order.to_string(), is_rev));
203
204        self
205    }
206
207    pub fn limit(&self) -> usize {
208        if self.limit == 0 {
209            return 50;
210        }
211
212        self.limit
213    }
214
215    pub fn offset(&self) -> usize {
216        self.offset
217    }
218
219    pub fn is_cond(&self) -> bool {
220        !self.conds.is_empty()
221    }
222
223    pub fn order_by(&self) -> &Vec<(String, bool)> {
224        &self.order_by
225    }
226}
227
228#[cfg(test)]
229mod tests {
230    use super::Expr;
231    use crate::store::{ExprOp, MessageStatus};
232    use serde_json::json;
233
234    #[test]
235    fn store_query_expr_eq_null() {
236        let expr = Expr::eq("a", json!(null));
237        assert_eq!(expr.key(), "a");
238        assert_eq!(expr.value(), &json!(null));
239        assert_eq!(expr.op, ExprOp::EQ);
240    }
241
242    #[test]
243    fn store_query_expr_ne_null() {
244        let expr = Expr::ne("a", json!(null));
245        assert_eq!(expr.key(), "a");
246        assert_eq!(expr.value(), &json!(null));
247        assert_eq!(expr.op, ExprOp::NE);
248    }
249
250    #[test]
251    fn store_query_expr_eq_str() {
252        let expr = Expr::eq("a", "abc");
253        assert_eq!(expr.key(), "a");
254        assert_eq!(expr.value(), &json!("abc"));
255        assert_eq!(expr.op, ExprOp::EQ);
256    }
257
258    #[test]
259    fn store_query_expr_ne_str() {
260        let expr = Expr::ne("a", "abc");
261        assert_eq!(expr.key(), "a");
262        assert_eq!(expr.value(), &json!("abc"));
263        assert_eq!(expr.op, ExprOp::NE);
264    }
265
266    #[test]
267    fn store_query_expr_eq_num() {
268        let expr = Expr::eq("a", 5);
269        assert_eq!(expr.key(), "a");
270        assert_eq!(expr.value(), &json!(5));
271        assert_eq!(expr.op, ExprOp::EQ);
272    }
273
274    #[test]
275    fn store_query_expr_ne_num() {
276        let expr = Expr::ne("a", 5);
277        assert_eq!(expr.key(), "a");
278        assert_eq!(expr.value(), &json!(5));
279        assert_eq!(expr.op, ExprOp::NE);
280    }
281
282    #[test]
283    fn store_query_expr_lt_num() {
284        let expr = Expr::lt("a", 5);
285        assert_eq!(expr.key(), "a");
286        assert_eq!(expr.value(), &json!(5));
287        assert_eq!(expr.op, ExprOp::LT);
288    }
289
290    #[test]
291    fn store_query_expr_le_num() {
292        let expr = Expr::le("a", 5);
293        assert_eq!(expr.key(), "a");
294        assert_eq!(expr.value(), &json!(5));
295        assert_eq!(expr.op, ExprOp::LE);
296    }
297
298    #[test]
299    fn store_query_expr_gt_num() {
300        let expr = Expr::gt("a", 5);
301        assert_eq!(expr.key(), "a");
302        assert_eq!(expr.value(), &json!(5));
303        assert_eq!(expr.op, ExprOp::GT);
304    }
305
306    #[test]
307    fn store_query_expr_ge_num() {
308        let expr = Expr::ge("a", 5);
309        assert_eq!(expr.key(), "a");
310        assert_eq!(expr.value(), &json!(5));
311        assert_eq!(expr.op, ExprOp::GE);
312    }
313
314    #[test]
315    fn store_query_expr_enum() {
316        let expr = Expr::eq("a", MessageStatus::Acked);
317        assert_eq!(expr.key(), "a");
318        assert_eq!(expr.value(), &json!(MessageStatus::Acked));
319    }
320}