1use crate::query::QueryBuilder;
4use crate::types::Common;
5use serde_json::Value;
6
7fn build_placeholders(len: usize) -> String {
8 if len == 0 {
9 return String::new();
10 }
11 let mut s = String::with_capacity(len * 3 - 2);
12 s.push('?');
13 for _ in 1..len {
14 s.push_str(", ?");
15 }
16 s
17}
18
19pub trait QueryCommon {
21 fn with(&mut self, alias: &str, chain_builder: crate::builder::ChainBuilder);
23
24 fn with_recursive(&mut self, alias: &str, chain_builder: crate::builder::ChainBuilder);
26
27 fn union(&mut self, chain_builder: crate::builder::ChainBuilder);
29
30 fn union_all(&mut self, chain_builder: crate::builder::ChainBuilder);
32
33 fn limit(&mut self, limit: usize);
35
36 fn offset(&mut self, offset: usize);
38
39 fn group_by(&mut self, columns: Vec<String>);
41
42 fn group_by_raw(&mut self, sql: &str, binds: Option<Vec<Value>>);
44
45 fn order_by(&mut self, column: &str, order: &str);
47
48 fn order_by_raw(&mut self, sql: &str, binds: Option<Vec<Value>>);
50}
51
52impl QueryCommon for QueryBuilder {
53 fn with(&mut self, alias: &str, chain_builder: crate::builder::ChainBuilder) {
54 self.query_common
55 .push(Common::With(alias.to_string(), false, chain_builder));
56 }
57
58 fn with_recursive(&mut self, alias: &str, chain_builder: crate::builder::ChainBuilder) {
59 self.query_common
60 .push(Common::With(alias.to_string(), true, chain_builder));
61 }
62
63 fn union(&mut self, chain_builder: crate::builder::ChainBuilder) {
64 self.query_common.push(Common::Union(false, chain_builder));
65 }
66
67 fn union_all(&mut self, chain_builder: crate::builder::ChainBuilder) {
68 self.query_common.push(Common::Union(true, chain_builder));
69 }
70
71 fn limit(&mut self, limit: usize) {
72 self.query_common.push(Common::Limit(limit));
73 }
74
75 fn offset(&mut self, offset: usize) {
76 self.query_common.push(Common::Offset(offset));
77 }
78
79 fn group_by(&mut self, columns: Vec<String>) {
80 self.query_common.push(Common::GroupBy(columns));
81 }
82
83 fn group_by_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) {
84 self.query_common
85 .push(Common::GroupByRaw(sql.to_string(), binds));
86 }
87
88 fn order_by(&mut self, column: &str, order: &str) {
89 self.query_common
90 .push(Common::OrderBy(column.to_string(), order.to_string()));
91 }
92
93 fn order_by_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) {
94 self.query_common
95 .push(Common::OrderByRaw(sql.to_string(), binds));
96 }
97}
98
99pub trait HavingClauses {
101 fn having(&mut self, column: &str, operator: &str, value: Value);
103
104 fn having_raw(&mut self, sql: &str, binds: Option<Vec<Value>>);
106
107 fn having_between(&mut self, column: &str, values: [Value; 2]);
109
110 fn having_in(&mut self, column: &str, values: Vec<Value>);
112
113 fn having_not_in(&mut self, column: &str, values: Vec<Value>);
115}
116
117impl HavingClauses for QueryBuilder {
118 fn having(&mut self, column: &str, operator: &str, value: Value) {
119 let sql = format!("{} {} ?", column, operator);
120 self.query_common
121 .push(Common::Having(sql, Some(vec![value])));
122 }
123
124 fn having_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) {
125 self.query_common
126 .push(Common::Having(sql.to_string(), binds));
127 }
128
129 fn having_between(&mut self, column: &str, values: [Value; 2]) {
130 let sql = format!("{} BETWEEN ? AND ?", column);
131 self.query_common
132 .push(Common::Having(sql, Some(values.to_vec())));
133 }
134
135 fn having_in(&mut self, column: &str, values: Vec<Value>) {
136 if values.is_empty() {
137 self.query_common
138 .push(Common::Having("1 = 0".to_string(), None));
139 return;
140 }
141 let placeholders = build_placeholders(values.len());
142 let sql = format!("{} IN ({})", column, placeholders);
143 self.query_common.push(Common::Having(sql, Some(values)));
144 }
145
146 fn having_not_in(&mut self, column: &str, values: Vec<Value>) {
147 if values.is_empty() {
148 self.query_common
149 .push(Common::Having("1 = 1".to_string(), None));
150 return;
151 }
152 let placeholders = build_placeholders(values.len());
153 let sql = format!("{} NOT IN ({})", column, placeholders);
154 self.query_common.push(Common::Having(sql, Some(values)));
155 }
156}
157
158pub trait WhereClauses {
160 fn where_eq(&mut self, column: &str, value: Value);
162
163 fn where_ne(&mut self, column: &str, value: Value);
165
166 fn where_in(&mut self, column: &str, values: Vec<Value>);
168
169 fn where_not_in(&mut self, column: &str, values: Vec<Value>);
171
172 fn where_null(&mut self, column: &str);
174
175 fn where_not_null(&mut self, column: &str);
177
178 fn where_between(&mut self, column: &str, values: [Value; 2]);
180
181 fn where_not_between(&mut self, column: &str, values: [Value; 2]);
183
184 fn where_like(&mut self, column: &str, value: Value);
186
187 fn where_not_like(&mut self, column: &str, value: Value);
189
190 fn where_ilike(&mut self, column: &str, value: Value);
192
193 fn where_gt(&mut self, column: &str, value: Value);
195
196 fn where_gte(&mut self, column: &str, value: Value);
198
199 fn where_lt(&mut self, column: &str, value: Value);
201
202 fn where_lte(&mut self, column: &str, value: Value);
204
205 fn where_column(&mut self, lhs: &str, operator: &str, rhs: &str);
207
208 fn where_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder));
210
211 fn where_not_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder));
213
214 fn where_json_contains(&mut self, column: &str, value: Value);
216
217 fn where_subquery(&mut self, query: impl FnOnce(&mut QueryBuilder));
219
220 fn or(&mut self) -> &mut QueryBuilder;
222
223 fn where_raw(&mut self, sql: &str, binds: Option<Vec<Value>>);
225}
226
227impl WhereClauses for QueryBuilder {
228 fn where_eq(&mut self, column: &str, value: Value) {
229 self.statement.push(crate::types::Statement::Value(
230 column.to_string(),
231 crate::query::Operator::Equal,
232 value,
233 ));
234 }
235
236 fn where_ne(&mut self, column: &str, value: Value) {
237 self.statement.push(crate::types::Statement::Value(
238 column.to_string(),
239 crate::query::Operator::NotEqual,
240 value,
241 ));
242 }
243
244 fn where_in(&mut self, column: &str, values: Vec<Value>) {
245 self.statement.push(crate::types::Statement::Value(
246 column.to_string(),
247 crate::query::Operator::In,
248 Value::Array(values),
249 ));
250 }
251
252 fn where_not_in(&mut self, column: &str, values: Vec<Value>) {
253 self.statement.push(crate::types::Statement::Value(
254 column.to_string(),
255 crate::query::Operator::NotIn,
256 Value::Array(values),
257 ));
258 }
259
260 fn where_null(&mut self, column: &str) {
261 self.statement.push(crate::types::Statement::Value(
262 column.to_string(),
263 crate::query::Operator::IsNull,
264 Value::Null,
265 ));
266 }
267
268 fn where_not_null(&mut self, column: &str) {
269 self.statement.push(crate::types::Statement::Value(
270 column.to_string(),
271 crate::query::Operator::IsNotNull,
272 Value::Null,
273 ));
274 }
275
276 fn where_between(&mut self, column: &str, values: [Value; 2]) {
277 self.statement.push(crate::types::Statement::Value(
278 column.to_string(),
279 crate::query::Operator::Between,
280 Value::Array(values.to_vec()),
281 ));
282 }
283
284 fn where_not_between(&mut self, column: &str, values: [Value; 2]) {
285 self.statement.push(crate::types::Statement::Value(
286 column.to_string(),
287 crate::query::Operator::NotBetween,
288 Value::Array(values.to_vec()),
289 ));
290 }
291
292 fn where_like(&mut self, column: &str, value: Value) {
293 self.statement.push(crate::types::Statement::Value(
294 column.to_string(),
295 crate::query::Operator::Like,
296 value,
297 ));
298 }
299
300 fn where_not_like(&mut self, column: &str, value: Value) {
301 self.statement.push(crate::types::Statement::Value(
302 column.to_string(),
303 crate::query::Operator::NotLike,
304 value,
305 ));
306 }
307
308 fn where_gt(&mut self, column: &str, value: Value) {
309 self.statement.push(crate::types::Statement::Value(
310 column.to_string(),
311 crate::query::Operator::GreaterThan,
312 value,
313 ));
314 }
315
316 fn where_gte(&mut self, column: &str, value: Value) {
317 self.statement.push(crate::types::Statement::Value(
318 column.to_string(),
319 crate::query::Operator::GreaterThanOrEqual,
320 value,
321 ));
322 }
323
324 fn where_lt(&mut self, column: &str, value: Value) {
325 self.statement.push(crate::types::Statement::Value(
326 column.to_string(),
327 crate::query::Operator::LessThan,
328 value,
329 ));
330 }
331
332 fn where_lte(&mut self, column: &str, value: Value) {
333 self.statement.push(crate::types::Statement::Value(
334 column.to_string(),
335 crate::query::Operator::LessThanOrEqual,
336 value,
337 ));
338 }
339
340 fn where_subquery(&mut self, query: impl FnOnce(&mut QueryBuilder)) {
341 let mut sub_query = QueryBuilder::new(self.client.clone());
342 query(&mut sub_query);
343 self.statement
344 .push(crate::types::Statement::SubChain(Box::new(sub_query)));
345 }
346
347 fn or(&mut self) -> &mut QueryBuilder {
348 let or_query = QueryBuilder::new(self.client.clone());
349 self.statement
350 .push(crate::types::Statement::OrChain(Box::new(or_query)));
351 self.statement.last_mut().unwrap().to_query_builder()
352 }
353
354 fn where_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) {
355 self.statement
356 .push(crate::types::Statement::Raw((sql.to_string(), binds)));
357 }
358
359 fn where_ilike(&mut self, column: &str, value: Value) {
360 let sql = format!("LOWER({}) LIKE LOWER(?)", column);
362 self.statement
363 .push(crate::types::Statement::Raw((sql, Some(vec![value]))));
364 }
365
366 fn where_column(&mut self, lhs: &str, operator: &str, rhs: &str) {
367 let sql = format!("{} {} {}", lhs, operator, rhs);
368 self.statement
369 .push(crate::types::Statement::Raw((sql, None)));
370 }
371
372 fn where_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder)) {
373 let mut sub_builder = crate::builder::ChainBuilder::new(self.client.clone());
374 query(&mut sub_builder);
375 let (sub_sql, sub_binds) = sub_builder.to_sql();
376 let sql = format!("EXISTS ({})", sub_sql);
377 self.statement
378 .push(crate::types::Statement::Raw((sql, Some(sub_binds))));
379 }
380
381 fn where_not_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder)) {
382 let mut sub_builder = crate::builder::ChainBuilder::new(self.client.clone());
383 query(&mut sub_builder);
384 let (sub_sql, sub_binds) = sub_builder.to_sql();
385 let sql = format!("NOT EXISTS ({})", sub_sql);
386 self.statement
387 .push(crate::types::Statement::Raw((sql, Some(sub_binds))));
388 }
389
390 fn where_json_contains(&mut self, column: &str, value: Value) {
391 let sql = format!("JSON_CONTAINS({}, ?)", column);
392 self.statement
393 .push(crate::types::Statement::Raw((sql, Some(vec![value]))));
394 }
395}