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);
123 self.query_common
124 .push(Common::Having(sql, Some(vec![value])));
125 }
126
127 fn having_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) {
128 self.query_common
129 .push(Common::Having(sql.to_string(), binds));
130 }
131
132 fn having_between(&mut self, column: &str, values: [Value; 2]) {
133 let sql = format!("{} BETWEEN ? AND ?", column);
135 self.query_common
136 .push(Common::Having(sql, Some(values.to_vec())));
137 }
138
139 fn having_in(&mut self, column: &str, values: Vec<Value>) {
140 if values.is_empty() {
141 self.query_common
142 .push(Common::Having("1 = 0".to_string(), None));
143 return;
144 }
145 let placeholders = build_placeholders(values.len());
146 let sql = format!("{} IN ({})", column, placeholders);
147 self.query_common.push(Common::Having(sql, Some(values)));
148 }
149
150 fn having_not_in(&mut self, column: &str, values: Vec<Value>) {
151 if values.is_empty() {
152 self.query_common
153 .push(Common::Having("1 = 1".to_string(), None));
154 return;
155 }
156 let placeholders = build_placeholders(values.len());
157 let sql = format!("{} NOT IN ({})", column, placeholders);
158 self.query_common.push(Common::Having(sql, Some(values)));
159 }
160}
161
162pub trait WhereClauses {
164 fn where_eq(&mut self, column: &str, value: Value);
166
167 fn where_ne(&mut self, column: &str, value: Value);
169
170 fn where_in(&mut self, column: &str, values: Vec<Value>);
172
173 fn where_not_in(&mut self, column: &str, values: Vec<Value>);
175
176 fn where_null(&mut self, column: &str);
178
179 fn where_not_null(&mut self, column: &str);
181
182 fn where_between(&mut self, column: &str, values: [Value; 2]);
184
185 fn where_not_between(&mut self, column: &str, values: [Value; 2]);
187
188 fn where_like(&mut self, column: &str, value: Value);
190
191 fn where_not_like(&mut self, column: &str, value: Value);
193
194 fn where_ilike(&mut self, column: &str, value: Value);
196
197 fn where_gt(&mut self, column: &str, value: Value);
199
200 fn where_gte(&mut self, column: &str, value: Value);
202
203 fn where_lt(&mut self, column: &str, value: Value);
205
206 fn where_lte(&mut self, column: &str, value: Value);
208
209 fn where_column(&mut self, lhs: &str, operator: &str, rhs: &str);
211
212 fn where_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder));
214
215 fn where_not_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder));
217
218 fn where_json_contains(&mut self, column: &str, value: Value);
220
221 fn where_subquery(&mut self, query: impl FnOnce(&mut QueryBuilder));
223
224 fn or(&mut self) -> &mut QueryBuilder;
226
227 fn where_raw(&mut self, sql: &str, binds: Option<Vec<Value>>);
229}
230
231impl WhereClauses for QueryBuilder {
232 fn where_eq(&mut self, column: &str, value: Value) {
233 self.statement.push(crate::types::Statement::Value(
234 column.to_string(),
235 crate::query::Operator::Equal,
236 value,
237 ));
238 }
239
240 fn where_ne(&mut self, column: &str, value: Value) {
241 self.statement.push(crate::types::Statement::Value(
242 column.to_string(),
243 crate::query::Operator::NotEqual,
244 value,
245 ));
246 }
247
248 fn where_in(&mut self, column: &str, values: Vec<Value>) {
249 self.statement.push(crate::types::Statement::Value(
250 column.to_string(),
251 crate::query::Operator::In,
252 Value::Array(values),
253 ));
254 }
255
256 fn where_not_in(&mut self, column: &str, values: Vec<Value>) {
257 self.statement.push(crate::types::Statement::Value(
258 column.to_string(),
259 crate::query::Operator::NotIn,
260 Value::Array(values),
261 ));
262 }
263
264 fn where_null(&mut self, column: &str) {
265 self.statement.push(crate::types::Statement::Value(
266 column.to_string(),
267 crate::query::Operator::IsNull,
268 Value::Null,
269 ));
270 }
271
272 fn where_not_null(&mut self, column: &str) {
273 self.statement.push(crate::types::Statement::Value(
274 column.to_string(),
275 crate::query::Operator::IsNotNull,
276 Value::Null,
277 ));
278 }
279
280 fn where_between(&mut self, column: &str, values: [Value; 2]) {
281 self.statement.push(crate::types::Statement::Value(
282 column.to_string(),
283 crate::query::Operator::Between,
284 Value::Array(values.to_vec()),
285 ));
286 }
287
288 fn where_not_between(&mut self, column: &str, values: [Value; 2]) {
289 self.statement.push(crate::types::Statement::Value(
290 column.to_string(),
291 crate::query::Operator::NotBetween,
292 Value::Array(values.to_vec()),
293 ));
294 }
295
296 fn where_like(&mut self, column: &str, value: Value) {
297 self.statement.push(crate::types::Statement::Value(
298 column.to_string(),
299 crate::query::Operator::Like,
300 value,
301 ));
302 }
303
304 fn where_not_like(&mut self, column: &str, value: Value) {
305 self.statement.push(crate::types::Statement::Value(
306 column.to_string(),
307 crate::query::Operator::NotLike,
308 value,
309 ));
310 }
311
312 fn where_gt(&mut self, column: &str, value: Value) {
313 self.statement.push(crate::types::Statement::Value(
314 column.to_string(),
315 crate::query::Operator::GreaterThan,
316 value,
317 ));
318 }
319
320 fn where_gte(&mut self, column: &str, value: Value) {
321 self.statement.push(crate::types::Statement::Value(
322 column.to_string(),
323 crate::query::Operator::GreaterThanOrEqual,
324 value,
325 ));
326 }
327
328 fn where_lt(&mut self, column: &str, value: Value) {
329 self.statement.push(crate::types::Statement::Value(
330 column.to_string(),
331 crate::query::Operator::LessThan,
332 value,
333 ));
334 }
335
336 fn where_lte(&mut self, column: &str, value: Value) {
337 self.statement.push(crate::types::Statement::Value(
338 column.to_string(),
339 crate::query::Operator::LessThanOrEqual,
340 value,
341 ));
342 }
343
344 fn where_subquery(&mut self, query: impl FnOnce(&mut QueryBuilder)) {
345 let mut sub_query = QueryBuilder::new(self.client.clone());
346 query(&mut sub_query);
347 self.statement
348 .push(crate::types::Statement::SubChain(Box::new(sub_query)));
349 }
350
351 fn or(&mut self) -> &mut QueryBuilder {
352 let or_query = QueryBuilder::new(self.client.clone());
353 self.statement
354 .push(crate::types::Statement::OrChain(Box::new(or_query)));
355 self.statement.last_mut().unwrap().to_query_builder()
356 }
357
358 fn where_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) {
359 self.statement
360 .push(crate::types::Statement::Raw((sql.to_string(), binds)));
361 }
362
363 fn where_ilike(&mut self, column: &str, value: Value) {
364 let column = crate::dialect::escape_identifier(column, &self.client);
366 let sql = format!("LOWER({}) LIKE LOWER(?)", column);
367 self.statement
368 .push(crate::types::Statement::Raw((sql, Some(vec![value]))));
369 }
370
371 fn where_column(&mut self, lhs: &str, operator: &str, rhs: &str) {
372 let lhs = crate::dialect::escape_identifier(lhs, &self.client);
373 let rhs = crate::dialect::escape_identifier(rhs, &self.client);
374 let sql = format!("{} {} {}", lhs, operator, rhs);
375 self.statement
376 .push(crate::types::Statement::Raw((sql, None)));
377 }
378
379 fn where_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder)) {
380 let mut sub_builder = crate::builder::ChainBuilder::new(self.client.clone());
381 query(&mut sub_builder);
382 let (sub_sql, sub_binds) = sub_builder.to_sql();
383 let sql = format!("EXISTS ({})", sub_sql);
384 self.statement
385 .push(crate::types::Statement::Raw((sql, Some(sub_binds))));
386 }
387
388 fn where_not_exists(&mut self, query: impl FnOnce(&mut crate::builder::ChainBuilder)) {
389 let mut sub_builder = crate::builder::ChainBuilder::new(self.client.clone());
390 query(&mut sub_builder);
391 let (sub_sql, sub_binds) = sub_builder.to_sql();
392 let sql = format!("NOT EXISTS ({})", sub_sql);
393 self.statement
394 .push(crate::types::Statement::Raw((sql, Some(sub_binds))));
395 }
396
397 fn where_json_contains(&mut self, column: &str, value: Value) {
398 let column = crate::dialect::escape_identifier(column, &self.client);
399 let sql = format!("JSON_CONTAINS({}, ?)", column);
400 self.statement
401 .push(crate::types::Statement::Raw((sql, Some(vec![value]))));
402 }
403}