1#[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
2use super::compare::JsonType;
3use crate::ast::{Comparable, Compare, Expression};
4use std::borrow::Cow;
5
6#[derive(Debug, Default, PartialEq, Clone)]
8pub struct Row<'a> {
9 pub values: Vec<Expression<'a>>,
10}
11
12impl<'a> Row<'a> {
13 pub fn new() -> Self {
14 Row { values: Vec::new() }
15 }
16
17 pub fn with_capacity(capacity: usize) -> Self {
18 Row {
19 values: Vec::with_capacity(capacity),
20 }
21 }
22
23 pub fn pop(&mut self) -> Option<Expression<'a>> {
24 self.values.pop()
25 }
26
27 pub fn push<T>(&mut self, value: T)
28 where
29 T: Into<Expression<'a>>,
30 {
31 self.values.push(value.into());
32 }
33
34 pub fn is_empty(&self) -> bool {
35 self.values.is_empty()
36 }
37
38 pub fn len(&self) -> usize {
39 self.values.len()
40 }
41
42 #[cfg(feature = "mssql")]
43 pub(crate) fn is_only_columns(&self) -> bool {
44 self.values.iter().all(|v| v.is_column())
45 }
46
47 #[cfg(feature = "mssql")]
48 pub(crate) fn into_columns(self) -> Vec<crate::ast::Column<'a>> {
49 let mut columns = Vec::with_capacity(self.len());
50
51 for expr in self.values.into_iter() {
52 columns.push(expr.into_column().unwrap());
53 }
54
55 columns
56 }
57}
58
59impl<'a> IntoIterator for Row<'a> {
60 type Item = Expression<'a>;
61 type IntoIter = std::vec::IntoIter<Self::Item>;
62
63 fn into_iter(self) -> Self::IntoIter {
64 self.values.into_iter()
65 }
66}
67
68impl<'a, T> From<Vec<T>> for Row<'a>
69where
70 T: Into<Expression<'a>>,
71{
72 fn from(vector: Vec<T>) -> Row<'a> {
73 let mut row = Row::with_capacity(vector.len());
74
75 for v in vector.into_iter() {
76 row.push(v.into());
77 }
78
79 row
80 }
81}
82
83impl<'a, A> From<(A,)> for Row<'a>
84where
85 A: Into<Expression<'a>>,
86{
87 fn from((val,): (A,)) -> Self {
88 let mut row = Row::with_capacity(1);
89 row.push(val);
90 row
91 }
92}
93
94impl<'a, A, B> From<(A, B)> for Row<'a>
95where
96 A: Into<Expression<'a>>,
97 B: Into<Expression<'a>>,
98{
99 fn from(vals: (A, B)) -> Self {
100 let mut row = Row::with_capacity(2);
101
102 row.push(vals.0);
103 row.push(vals.1);
104
105 row
106 }
107}
108
109impl<'a, A, B, C> From<(A, B, C)> for Row<'a>
110where
111 A: Into<Expression<'a>>,
112 B: Into<Expression<'a>>,
113 C: Into<Expression<'a>>,
114{
115 fn from(vals: (A, B, C)) -> Self {
116 let mut row = Row::with_capacity(3);
117
118 row.push(vals.0);
119 row.push(vals.1);
120 row.push(vals.2);
121
122 row
123 }
124}
125
126impl<'a, A, B, C, D> From<(A, B, C, D)> for Row<'a>
127where
128 A: Into<Expression<'a>>,
129 B: Into<Expression<'a>>,
130 C: Into<Expression<'a>>,
131 D: Into<Expression<'a>>,
132{
133 fn from(vals: (A, B, C, D)) -> Self {
134 let mut row = Row::with_capacity(4);
135
136 row.push(vals.0);
137 row.push(vals.1);
138 row.push(vals.2);
139 row.push(vals.3);
140
141 row
142 }
143}
144
145impl<'a, A, B, C, D, E> From<(A, B, C, D, E)> for Row<'a>
146where
147 A: Into<Expression<'a>>,
148 B: Into<Expression<'a>>,
149 C: Into<Expression<'a>>,
150 D: Into<Expression<'a>>,
151 E: Into<Expression<'a>>,
152{
153 fn from(vals: (A, B, C, D, E)) -> Self {
154 let mut row = Row::with_capacity(5);
155
156 row.push(vals.0);
157 row.push(vals.1);
158 row.push(vals.2);
159 row.push(vals.3);
160 row.push(vals.4);
161
162 row
163 }
164}
165
166impl<'a> Comparable<'a> for Row<'a> {
167 fn equals<T>(self, comparison: T) -> Compare<'a>
168 where
169 T: Into<Expression<'a>>,
170 {
171 let value: Expression<'a> = self.into();
172 value.equals(comparison)
173 }
174
175 fn not_equals<T>(self, comparison: T) -> Compare<'a>
176 where
177 T: Into<Expression<'a>>,
178 {
179 let value: Expression<'a> = self.into();
180 value.not_equals(comparison)
181 }
182
183 fn less_than<T>(self, comparison: T) -> Compare<'a>
184 where
185 T: Into<Expression<'a>>,
186 {
187 let value: Expression<'a> = self.into();
188 value.less_than(comparison)
189 }
190
191 fn less_than_or_equals<T>(self, comparison: T) -> Compare<'a>
192 where
193 T: Into<Expression<'a>>,
194 {
195 let value: Expression<'a> = self.into();
196 value.less_than_or_equals(comparison)
197 }
198
199 fn greater_than<T>(self, comparison: T) -> Compare<'a>
200 where
201 T: Into<Expression<'a>>,
202 {
203 let value: Expression<'a> = self.into();
204 value.greater_than(comparison)
205 }
206
207 fn greater_than_or_equals<T>(self, comparison: T) -> Compare<'a>
208 where
209 T: Into<Expression<'a>>,
210 {
211 let value: Expression<'a> = self.into();
212 value.greater_than_or_equals(comparison)
213 }
214
215 fn in_selection<T>(self, selection: T) -> Compare<'a>
216 where
217 T: Into<Expression<'a>>,
218 {
219 let value: Expression<'a> = self.into();
220 value.in_selection(selection)
221 }
222
223 fn not_in_selection<T>(self, selection: T) -> Compare<'a>
224 where
225 T: Into<Expression<'a>>,
226 {
227 let value: Expression<'a> = self.into();
228 value.not_in_selection(selection)
229 }
230
231 fn like<T>(self, pattern: T) -> Compare<'a>
232 where
233 T: Into<Expression<'a>>,
234 {
235 let value: Expression<'a> = self.into();
236 value.like(pattern)
237 }
238
239 fn not_like<T>(self, pattern: T) -> Compare<'a>
240 where
241 T: Into<Expression<'a>>,
242 {
243 let value: Expression<'a> = self.into();
244 value.not_like(pattern)
245 }
246
247 #[allow(clippy::wrong_self_convention)]
248 fn is_null(self) -> Compare<'a> {
249 let value: Expression<'a> = self.into();
250 value.is_null()
251 }
252
253 #[allow(clippy::wrong_self_convention)]
254 fn is_not_null(self) -> Compare<'a> {
255 let value: Expression<'a> = self.into();
256 value.is_not_null()
257 }
258
259 fn between<T, V>(self, left: T, right: V) -> Compare<'a>
260 where
261 T: Into<Expression<'a>>,
262 V: Into<Expression<'a>>,
263 {
264 let value: Expression<'a> = self.into();
265 value.between(left, right)
266 }
267
268 fn not_between<T, V>(self, left: T, right: V) -> Compare<'a>
269 where
270 T: Into<Expression<'a>>,
271 V: Into<Expression<'a>>,
272 {
273 let value: Expression<'a> = self.into();
274 value.not_between(left, right)
275 }
276
277 fn compare_raw<T, V>(self, raw_comparator: T, right: V) -> Compare<'a>
278 where
279 T: Into<Cow<'a, str>>,
280 V: Into<Expression<'a>>,
281 {
282 let value: Expression<'a> = self.into();
283 value.compare_raw(raw_comparator, right)
284 }
285
286 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
287 fn json_array_contains<T>(self, item: T) -> Compare<'a>
288 where
289 T: Into<Expression<'a>>,
290 {
291 let value: Expression<'a> = self.into();
292
293 value.json_array_contains(item)
294 }
295
296 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
297 fn json_array_not_contains<T>(self, item: T) -> Compare<'a>
298 where
299 T: Into<Expression<'a>>,
300 {
301 let value: Expression<'a> = self.into();
302
303 value.json_array_not_contains(item)
304 }
305
306 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
307 fn json_array_begins_with<T>(self, item: T) -> Compare<'a>
308 where
309 T: Into<Expression<'a>>,
310 {
311 let value: Expression<'a> = self.into();
312
313 value.json_array_begins_with(item)
314 }
315
316 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
317 fn json_array_not_begins_with<T>(self, item: T) -> Compare<'a>
318 where
319 T: Into<Expression<'a>>,
320 {
321 let value: Expression<'a> = self.into();
322
323 value.json_array_not_begins_with(item)
324 }
325
326 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
327 fn json_array_ends_into<T>(self, item: T) -> Compare<'a>
328 where
329 T: Into<Expression<'a>>,
330 {
331 let value: Expression<'a> = self.into();
332
333 value.json_array_ends_into(item)
334 }
335
336 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
337 fn json_array_not_ends_into<T>(self, item: T) -> Compare<'a>
338 where
339 T: Into<Expression<'a>>,
340 {
341 let value: Expression<'a> = self.into();
342
343 value.json_array_not_ends_into(item)
344 }
345
346 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
347 fn json_type_equals<T>(self, json_type: T) -> Compare<'a>
348 where
349 T: Into<JsonType<'a>>,
350 {
351 let value: Expression<'a> = self.into();
352
353 value.json_type_equals(json_type)
354 }
355
356 #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
357 fn json_type_not_equals<T>(self, json_type: T) -> Compare<'a>
358 where
359 T: Into<JsonType<'a>>,
360 {
361 let value: Expression<'a> = self.into();
362
363 value.json_type_not_equals(json_type)
364 }
365
366 #[cfg(feature = "postgresql")]
367 fn matches<T>(self, query: T) -> Compare<'a>
368 where
369 T: Into<Cow<'a, str>>,
370 {
371 let value: Expression<'a> = self.into();
372
373 value.matches(query)
374 }
375
376 #[cfg(feature = "postgresql")]
377 fn not_matches<T>(self, query: T) -> Compare<'a>
378 where
379 T: Into<Cow<'a, str>>,
380 {
381 let value: Expression<'a> = self.into();
382
383 value.not_matches(query)
384 }
385
386 #[cfg(feature = "postgresql")]
387 fn any(self) -> Compare<'a> {
388 let value: Expression<'a> = self.into();
389
390 value.any()
391 }
392
393 #[cfg(feature = "postgresql")]
394 fn all(self) -> Compare<'a> {
395 let value: Expression<'a> = self.into();
396
397 value.all()
398 }
399}