|
1 | 1 | use std::collections::{BTreeMap, HashMap};
|
2 | 2 |
|
3 |
| -use futures::{future, stream, StreamExt}; |
4 | 3 | use rayon::prelude::*;
|
5 | 4 | use uuid::Uuid;
|
6 | 5 | use wql::{Algebra, Clause, ToSelect, Types, Value};
|
@@ -68,73 +67,105 @@ async fn filter_where_clauses(
|
68 | 67 | clauses: &[Clause],
|
69 | 68 | ) -> BTreeMap<Uuid, HashMap<String, Types>> {
|
70 | 69 | let default = String::new();
|
71 |
| - stream::iter(states) |
72 |
| - .filter(|(_, state)| { |
73 |
| - future::ready( |
74 |
| - clauses |
75 |
| - .par_iter() |
76 |
| - .map(|clause| match clause { |
77 |
| - Clause::ValueAttribution(_, _, _) => true, |
78 |
| - Clause::Or(_, inner_clauses) => { |
79 |
| - or_clauses(state, &args_to_key, inner_clauses) |
| 70 | + let mut states = states.clone(); |
| 71 | + for clause in clauses { |
| 72 | + match clause { |
| 73 | + Clause::ValueAttribution(_, _, _) => {} |
| 74 | + Clause::Or(_, inner_clauses) => { |
| 75 | + for (id, state) in states.clone() { |
| 76 | + if !or_clauses(&state, &args_to_key, &inner_clauses) { |
| 77 | + states.remove(&id); |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + Clause::ContainsKeyValue(_, key, value) => { |
| 82 | + for (id, state) in states.clone() { |
| 83 | + if !state.get(key).map_or(false, |v| value == v) { |
| 84 | + states.remove(&id); |
| 85 | + } |
| 86 | + } |
| 87 | + } |
| 88 | + Clause::SimpleComparisonFunction(f, key, value) => { |
| 89 | + let key = args_to_key.get(key).unwrap_or(&default); |
| 90 | + for (id, state) in states.clone() { |
| 91 | + state.get(key).map(|v| match f { |
| 92 | + wql::Function::Eq => { |
| 93 | + if !(v == value) { |
| 94 | + states.remove(&id); |
| 95 | + } |
80 | 96 | }
|
81 |
| - Clause::ContainsKeyValue(_, key, value) => { |
82 |
| - state.get(key).map_or(false, |v| value == v) |
| 97 | + wql::Function::NotEq => { |
| 98 | + if !(v != value) { |
| 99 | + states.remove(&id); |
| 100 | + } |
83 | 101 | }
|
84 |
| - Clause::SimpleComparisonFunction(f, key, value) => { |
85 |
| - let key = args_to_key.get(key).unwrap_or(&default); |
86 |
| - state.get(key).map_or(false, |v| match f { |
87 |
| - wql::Function::Eq => v == value, |
88 |
| - wql::Function::NotEq => v != value, |
89 |
| - wql::Function::GEq => v >= value, |
90 |
| - wql::Function::G => v > value, |
91 |
| - wql::Function::LEq => v <= value, |
92 |
| - wql::Function::L => { |
93 |
| - println!("{:?} < {:?} = {}", v, value, v < value); |
94 |
| - v < value |
95 |
| - } |
96 |
| - wql::Function::Like => { |
97 |
| - if let (Types::String(content), Types::String(regex)) = |
98 |
| - (v, value) |
99 |
| - { |
100 |
| - let pattern = regex.replace("%", ""); |
101 |
| - if regex.starts_with('%') && regex.ends_with('%') { |
102 |
| - content.contains(&pattern) |
103 |
| - } else if regex.starts_with('%') { |
104 |
| - content.ends_with(&pattern) |
105 |
| - } else if regex.ends_with('%') { |
106 |
| - content.starts_with(&pattern) |
107 |
| - } else { |
108 |
| - content.contains(&pattern) |
109 |
| - } |
110 |
| - } else { |
111 |
| - false |
112 |
| - } |
113 |
| - } |
114 |
| - _ => false, |
115 |
| - }) |
| 102 | + wql::Function::GEq => { |
| 103 | + if !(v >= &value) { |
| 104 | + states.remove(&id); |
| 105 | + } |
116 | 106 | }
|
117 |
| - Clause::ComplexComparisonFunctions(wql::Function::In, key, set) => { |
118 |
| - let key = args_to_key.get(key).unwrap_or(&default); |
119 |
| - state.get(key).map_or(false, |v| set.contains(v)) |
| 107 | + wql::Function::G => { |
| 108 | + if !(v > &value) { |
| 109 | + states.remove(&id); |
| 110 | + } |
120 | 111 | }
|
121 |
| - Clause::ComplexComparisonFunctions( |
122 |
| - wql::Function::Between, |
123 |
| - key, |
124 |
| - start_end, |
125 |
| - ) => { |
126 |
| - let key = args_to_key.get(key).unwrap_or(&default); |
127 |
| - state |
128 |
| - .get(key) |
129 |
| - .map_or(false, |v| v >= &start_end[0] && v <= &start_end[1]) |
| 112 | + wql::Function::LEq => { |
| 113 | + if !(v <= &value) { |
| 114 | + states.remove(&id); |
| 115 | + } |
130 | 116 | }
|
131 |
| - _ => false, |
132 |
| - }) |
133 |
| - .all(|f| f), |
134 |
| - ) |
135 |
| - }) |
136 |
| - .collect::<BTreeMap<Uuid, HashMap<String, Types>>>() |
137 |
| - .await |
| 117 | + wql::Function::L => { |
| 118 | + if !(v < &value) { |
| 119 | + states.remove(&id); |
| 120 | + } |
| 121 | + } |
| 122 | + wql::Function::Like => { |
| 123 | + if let (Types::String(content), Types::String(regex)) = (v, value) { |
| 124 | + let pattern = regex.replace("%", ""); |
| 125 | + |
| 126 | + if (regex.starts_with('%') |
| 127 | + && regex.ends_with('%') |
| 128 | + && content.contains(&pattern)) |
| 129 | + || (regex.starts_with('%') && content.ends_with(&pattern)) |
| 130 | + || (regex.ends_with('%') && content.starts_with(&pattern)) |
| 131 | + || content.contains(&pattern) |
| 132 | + { |
| 133 | + () |
| 134 | + } else { |
| 135 | + states.remove(&id); |
| 136 | + } |
| 137 | + } else { |
| 138 | + states.remove(&id); |
| 139 | + } |
| 140 | + } |
| 141 | + _ => {} |
| 142 | + }); |
| 143 | + } |
| 144 | + } |
| 145 | + Clause::ComplexComparisonFunctions(wql::Function::In, key, set) => { |
| 146 | + let key = args_to_key.get(key).unwrap_or(&default); |
| 147 | + for (id, state) in states.clone() { |
| 148 | + if !state.get(key).map_or(false, |v| set.contains(v)) { |
| 149 | + states.remove(&id); |
| 150 | + } |
| 151 | + } |
| 152 | + } |
| 153 | + Clause::ComplexComparisonFunctions(wql::Function::Between, key, start_end) => { |
| 154 | + let key = args_to_key.get(key).unwrap_or(&default); |
| 155 | + for (id, state) in states.clone() { |
| 156 | + if !state |
| 157 | + .get(key) |
| 158 | + .map_or(false, |v| v >= &start_end[0] && v <= &start_end[1]) |
| 159 | + { |
| 160 | + states.remove(&id); |
| 161 | + } |
| 162 | + } |
| 163 | + } |
| 164 | + _ => (), |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + states |
138 | 169 | }
|
139 | 170 |
|
140 | 171 | fn or_clauses(
|
|
0 commit comments