1use std::collections::HashMap;
5
6use serde::{Deserialize, Serialize};
7use tardis::{basic::result::TardisResult, serde_json::Value};
8
9use crate::enumeration::BasicQueryOpKind;
10
11use tardis::web::poem_openapi;
12
13#[derive(Serialize, Deserialize, Debug, Clone, poem_openapi::Object)]
17pub struct BasicQueryCondInfo {
18 #[oai(validator(min_length = "1"))]
20 pub field: String,
21 pub op: BasicQueryOpKind,
23 pub value: Value,
25}
26
27impl BasicQueryCondInfo {
28 pub fn check_or_and_conds(conds: &[Vec<BasicQueryCondInfo>], check_vars: &HashMap<String, Value>) -> TardisResult<bool> {
34 let is_match = conds.iter().any(|and_conds| {
35 and_conds.iter().all(|cond| match check_vars.get(&cond.field) {
36 Some(check_val) => match &cond.op {
37 BasicQueryOpKind::Eq => &cond.value == check_val,
38 BasicQueryOpKind::Ne => &cond.value != check_val,
39 BasicQueryOpKind::Gt => {
40 if cond.value.is_f64() && check_val.is_f64() {
41 cond.value.as_f64().unwrap_or(0.0) < check_val.as_f64().unwrap_or(0.0)
42 } else if cond.value.is_i64() && check_val.is_i64() {
43 cond.value.as_i64().unwrap_or(0) < check_val.as_i64().unwrap_or(0)
44 } else if cond.value.is_u64() && check_val.is_u64() {
45 cond.value.as_u64().unwrap_or(0) < check_val.as_u64().unwrap_or(0)
46 } else {
47 false
48 }
49 }
50 BasicQueryOpKind::Ge => {
51 if cond.value.is_f64() && check_val.is_f64() {
52 cond.value.as_f64().unwrap_or(0.0) <= check_val.as_f64().unwrap_or(0.0)
53 } else if cond.value.is_i64() && check_val.is_i64() {
54 cond.value.as_i64().unwrap_or(0) <= check_val.as_i64().unwrap_or(0)
55 } else if cond.value.is_u64() && check_val.is_u64() {
56 cond.value.as_u64().unwrap_or(0) <= check_val.as_u64().unwrap_or(0)
57 } else {
58 false
59 }
60 }
61 BasicQueryOpKind::Lt => {
62 if cond.value.is_f64() && check_val.is_f64() {
63 cond.value.as_f64().unwrap_or(0.0) > check_val.as_f64().unwrap_or(0.0)
64 } else if cond.value.is_i64() && check_val.is_i64() {
65 cond.value.as_i64().unwrap_or(0) > check_val.as_i64().unwrap_or(0)
66 } else if cond.value.is_u64() && check_val.is_u64() {
67 cond.value.as_u64().unwrap_or(0) > check_val.as_u64().unwrap_or(0)
68 } else {
69 false
70 }
71 }
72 BasicQueryOpKind::Le => {
73 if cond.value.is_f64() && check_val.is_f64() {
74 cond.value.as_f64().unwrap_or(0.0) >= check_val.as_f64().unwrap_or(0.0)
75 } else if cond.value.is_i64() && check_val.is_i64() {
76 cond.value.as_i64().unwrap_or(0) >= check_val.as_i64().unwrap_or(0)
77 } else if cond.value.is_u64() && check_val.is_u64() {
78 cond.value.as_u64().unwrap_or(0) >= check_val.as_u64().unwrap_or(0)
79 } else {
80 false
81 }
82 }
83 BasicQueryOpKind::Like
84 | BasicQueryOpKind::LLike
85 | BasicQueryOpKind::RLike
86 | BasicQueryOpKind::NotLike
87 | BasicQueryOpKind::NotLLike
88 | BasicQueryOpKind::NotRLike => {
89 check_val.as_str().map(|check_val_str| cond.value.as_str().map(|cond_val_str| check_val_str.contains(cond_val_str)).unwrap_or(false)).unwrap_or(false)
90 }
91 BasicQueryOpKind::In => check_val.as_array().map(|check_val_arr| check_val_arr.contains(&cond.value)).unwrap_or(false),
92 BasicQueryOpKind::NotIn => check_val.as_array().map(|check_val_arr| check_val_arr.contains(&cond.value)).unwrap_or(false),
93 BasicQueryOpKind::IsNull => false,
94 BasicQueryOpKind::IsNotNull => false,
95 BasicQueryOpKind::IsNullOrEmpty => false,
96 BasicQueryOpKind::Len => false,
97 },
98 None => false,
99 })
100 });
101 Ok(is_match)
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use std::collections::HashMap;
108
109 use tardis::{basic::result::TardisResult, serde_json::json};
110
111 use crate::{dto::BasicQueryCondInfo, enumeration::BasicQueryOpKind};
112
113 #[test]
114 fn test_check_or_and_conds() -> TardisResult<()> {
115 assert!(BasicQueryCondInfo::check_or_and_conds(&[vec![]], &HashMap::new())?);
116 assert!(
117 !(BasicQueryCondInfo::check_or_and_conds(
118 &[vec![BasicQueryCondInfo {
119 field: "name".to_string(),
120 op: BasicQueryOpKind::Eq,
121 value: json!("gdxr")
122 }]],
123 &HashMap::new()
124 )?)
125 );
126 assert!(BasicQueryCondInfo::check_or_and_conds(
128 &[vec![BasicQueryCondInfo {
129 field: "name".to_string(),
130 op: BasicQueryOpKind::Eq,
131 value: json!("gdxr")
132 }]],
133 &HashMap::from([("name".to_string(), json!("gdxr"))])
134 )?);
135 assert!(BasicQueryCondInfo::check_or_and_conds(
137 &[vec![BasicQueryCondInfo {
138 field: "gt".to_string(),
139 op: BasicQueryOpKind::Gt,
140 value: json!(0)
141 }]],
142 &HashMap::from([("gt".to_string(), json!(1))])
143 )?);
144 assert!(
145 !(BasicQueryCondInfo::check_or_and_conds(
146 &[vec![BasicQueryCondInfo {
147 field: "gt".to_string(),
148 op: BasicQueryOpKind::Gt,
149 value: json!(0)
150 }]],
151 &HashMap::from([("gt".to_string(), json!(-1))])
152 )?)
153 );
154 assert!(BasicQueryCondInfo::check_or_and_conds(
156 &[vec![BasicQueryCondInfo {
157 field: "ge".to_string(),
158 op: BasicQueryOpKind::Ge,
159 value: json!(0)
160 }]],
161 &HashMap::from([("ge".to_string(), json!(0))])
162 )?);
163 assert!(
164 !(BasicQueryCondInfo::check_or_and_conds(
165 &[vec![BasicQueryCondInfo {
166 field: "ge".to_string(),
167 op: BasicQueryOpKind::Ge,
168 value: json!(0)
169 }]],
170 &HashMap::from([("ge".to_string(), json!(-1))])
171 )?)
172 );
173 assert!(BasicQueryCondInfo::check_or_and_conds(
175 &[vec![BasicQueryCondInfo {
176 field: "lt".to_string(),
177 op: BasicQueryOpKind::Lt,
178 value: json!(0)
179 }]],
180 &HashMap::from([("lt".to_string(), json!(-1))])
181 )?);
182 assert!(
183 !(BasicQueryCondInfo::check_or_and_conds(
184 &[vec![BasicQueryCondInfo {
185 field: "lt".to_string(),
186 op: BasicQueryOpKind::Lt,
187 value: json!(0)
188 }]],
189 &HashMap::from([("lt".to_string(), json!(1))])
190 )?)
191 );
192 assert!(BasicQueryCondInfo::check_or_and_conds(
194 &[vec![BasicQueryCondInfo {
195 field: "le".to_string(),
196 op: BasicQueryOpKind::Le,
197 value: json!(0)
198 }]],
199 &HashMap::from([("le".to_string(), json!(0))])
200 )?);
201 assert!(
202 !(BasicQueryCondInfo::check_or_and_conds(
203 &[vec![BasicQueryCondInfo {
204 field: "le".to_string(),
205 op: BasicQueryOpKind::Le,
206 value: json!(0)
207 }]],
208 &HashMap::from([("le".to_string(), json!(1))])
209 )?)
210 );
211 assert!(
212 !(BasicQueryCondInfo::check_or_and_conds(
213 &[vec![BasicQueryCondInfo {
214 field: "le".to_string(),
215 op: BasicQueryOpKind::Le,
216 value: json!("ssss".to_string())
217 }]],
218 &HashMap::from([("le".to_string(), json!(1))])
219 )?)
220 );
221 assert!(BasicQueryCondInfo::check_or_and_conds(
223 &[vec![BasicQueryCondInfo {
224 field: "like".to_string(),
225 op: BasicQueryOpKind::Like,
226 value: json!("dx")
227 }]],
228 &HashMap::from([("like".to_string(), json!("gdxr"))])
229 )?);
230 assert!(
231 !(BasicQueryCondInfo::check_or_and_conds(
232 &[vec![BasicQueryCondInfo {
233 field: "like".to_string(),
234 op: BasicQueryOpKind::Like,
235 value: json!("ddd")
236 }]],
237 &HashMap::from([("like".to_string(), json!("gdxr"))])
238 )?)
239 );
240 assert!(
241 !(BasicQueryCondInfo::check_or_and_conds(
242 &[vec![BasicQueryCondInfo {
243 field: "like".to_string(),
244 op: BasicQueryOpKind::Like,
245 value: json!(111)
246 }]],
247 &HashMap::from([("like".to_string(), json!("dx"))])
248 )?)
249 );
250 assert!(
251 !(BasicQueryCondInfo::check_or_and_conds(
252 &[vec![BasicQueryCondInfo {
253 field: "like".to_string(),
254 op: BasicQueryOpKind::Like,
255 value: json!("gdxr")
256 }]],
257 &HashMap::from([("like".to_string(), json!(1))])
258 )?)
259 );
260 assert!(BasicQueryCondInfo::check_or_and_conds(
262 &[vec![BasicQueryCondInfo {
263 field: "in".to_string(),
264 op: BasicQueryOpKind::In,
265 value: json!("gdxr")
266 }]],
267 &HashMap::from([("in".to_string(), json!(["gdxr", "ddd"]))])
268 )?);
269 assert!(
270 !(BasicQueryCondInfo::check_or_and_conds(
271 &[vec![BasicQueryCondInfo {
272 field: "in".to_string(),
273 op: BasicQueryOpKind::In,
274 value: json!("gdxr")
275 }]],
276 &HashMap::from([("in".to_string(), json!("gdxr"))])
277 )?)
278 );
279 assert!(
280 !(BasicQueryCondInfo::check_or_and_conds(
281 &[vec![BasicQueryCondInfo {
282 field: "in".to_string(),
283 op: BasicQueryOpKind::In,
284 value: json!(["gdxr"])
285 }]],
286 &HashMap::from([("in".to_string(), json!("gdxr"))])
287 )?)
288 );
289 assert!(BasicQueryCondInfo::check_or_and_conds(
291 &[vec![
292 BasicQueryCondInfo {
293 field: "in".to_string(),
294 op: BasicQueryOpKind::In,
295 value: json!("gdxr")
296 },
297 BasicQueryCondInfo {
298 field: "like".to_string(),
299 op: BasicQueryOpKind::Like,
300 value: json!("dx")
301 }
302 ]],
303 &HashMap::from([("in".to_string(), json!(["gdxr"])), ("like".to_string(), json!("gdxr"))])
304 )?);
305 assert!(
306 !(BasicQueryCondInfo::check_or_and_conds(
307 &[vec![
308 BasicQueryCondInfo {
309 field: "in".to_string(),
310 op: BasicQueryOpKind::In,
311 value: json!("gdxr")
312 },
313 BasicQueryCondInfo {
314 field: "like".to_string(),
315 op: BasicQueryOpKind::Like,
316 value: json!("dx")
317 }
318 ]],
319 &HashMap::from([("in".to_string(), json!(["gdxr"]))])
320 )?)
321 );
322 assert!(
323 !(BasicQueryCondInfo::check_or_and_conds(
324 &[vec![
325 BasicQueryCondInfo {
326 field: "in".to_string(),
327 op: BasicQueryOpKind::In,
328 value: json!("gdxr")
329 },
330 BasicQueryCondInfo {
331 field: "like".to_string(),
332 op: BasicQueryOpKind::Like,
333 value: json!("dx11")
334 }
335 ]],
336 &HashMap::from([("in".to_string(), json!(["gdxr"])), ("like".to_string(), json!("gdxr"))])
337 )?)
338 );
339 assert!(BasicQueryCondInfo::check_or_and_conds(
341 &[
342 vec![BasicQueryCondInfo {
343 field: "in".to_string(),
344 op: BasicQueryOpKind::In,
345 value: json!("gdxr")
346 }],
347 vec![BasicQueryCondInfo {
348 field: "like".to_string(),
349 op: BasicQueryOpKind::Like,
350 value: json!("dx")
351 }]
352 ],
353 &HashMap::from([("in".to_string(), json!(["gdxr"])), ("like".to_string(), json!("gdxr"))])
354 )?);
355 assert!(BasicQueryCondInfo::check_or_and_conds(
356 &[
357 vec![BasicQueryCondInfo {
358 field: "in".to_string(),
359 op: BasicQueryOpKind::In,
360 value: json!("gdxr")
361 }],
362 vec![BasicQueryCondInfo {
363 field: "like".to_string(),
364 op: BasicQueryOpKind::Like,
365 value: json!("dx")
366 }]
367 ],
368 &HashMap::from([("in".to_string(), json!(["gdxr"]))])
369 )?);
370 assert!(BasicQueryCondInfo::check_or_and_conds(
371 &[
372 vec![BasicQueryCondInfo {
373 field: "in".to_string(),
374 op: BasicQueryOpKind::In,
375 value: json!(["gdxr"])
376 }],
377 vec![BasicQueryCondInfo {
378 field: "like".to_string(),
379 op: BasicQueryOpKind::Like,
380 value: json!("dx")
381 }]
382 ],
383 &HashMap::from([("in".to_string(), json!(["gdxr"])), ("like".to_string(), json!("gdxr"))])
384 )?);
385 assert!(
386 !(BasicQueryCondInfo::check_or_and_conds(
387 &[
388 vec![BasicQueryCondInfo {
389 field: "in".to_string(),
390 op: BasicQueryOpKind::In,
391 value: json!("gdxr1")
392 }],
393 vec![BasicQueryCondInfo {
394 field: "like".to_string(),
395 op: BasicQueryOpKind::Like,
396 value: json!("dx")
397 }]
398 ],
399 &HashMap::from([("in".to_string(), json!(["gdxr"]))])
400 )?)
401 );
402 Ok(())
403 }
404}