1use crate::expr::{Condition, Expr, IntoCondition, Order};
21use crate::iden::{ColumnRef, Ident, IntoIden, TableRef};
22use crate::value::Value;
23
24#[derive(Debug)]
27pub struct Query;
28
29impl Query {
30 pub fn select() -> Select {
32 Select::default()
33 }
34
35 pub fn insert() -> Insert {
37 Insert::default()
38 }
39
40 pub fn update() -> Update {
42 Update::default()
43 }
44
45 pub fn delete() -> Delete {
47 Delete::default()
48 }
49}
50
51#[derive(Clone, Debug, PartialEq)]
53pub enum SelectItem {
54 Expr(Expr),
56}
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq)]
60pub enum JoinType {
61 Inner,
63 Left,
65 Cross,
67}
68
69#[derive(Clone, Debug, PartialEq)]
71pub struct Join {
72 pub kind: JoinType,
74 pub table: TableRef,
76 pub on: Option<Expr>,
78}
79
80#[derive(Clone, Debug, Default, PartialEq)]
82pub enum Returning {
83 #[default]
85 None,
86 All,
88 Columns(Vec<ColumnRef>),
90}
91
92#[derive(Clone, Debug, Default, PartialEq)]
94pub struct Select {
95 pub(crate) distinct: bool,
97 pub(crate) items: Vec<SelectItem>,
99 pub(crate) from: Vec<TableRef>,
101 pub(crate) from_subquery: Option<(Box<Select>, Ident)>,
103 pub(crate) joins: Vec<Join>,
105 pub(crate) r#where: Condition,
107 pub(crate) group_by: Vec<Expr>,
109 pub(crate) having: Condition,
111 pub(crate) order_by: Vec<(Expr, Order)>,
113 pub(crate) limit: Option<u64>,
115 pub(crate) offset: Option<u64>,
117}
118
119impl Select {
120 pub fn new() -> Self {
122 Self {
123 r#where: Condition::all(),
124 having: Condition::all(),
125 ..Default::default()
126 }
127 }
128
129 #[must_use]
131 pub fn distinct(mut self) -> Self {
132 self.distinct = true;
133 self
134 }
135
136 #[must_use]
138 pub fn column(mut self, column: impl Into<ColumnRef>) -> Self {
139 self.items
140 .push(SelectItem::Expr(Expr::Column(column.into())));
141 self
142 }
143
144 #[must_use]
146 pub fn columns<C: Into<ColumnRef>>(mut self, columns: impl IntoIterator<Item = C>) -> Self {
147 for c in columns {
148 self = self.column(c);
149 }
150 self
151 }
152
153 #[must_use]
155 pub fn expr(mut self, expr: Expr) -> Self {
156 self.items.push(SelectItem::Expr(expr));
157 self
158 }
159
160 #[must_use]
162 pub fn expr_as(self, expr: Expr, alias: impl IntoIden) -> Self {
163 self.expr(expr.alias(alias))
164 }
165
166 pub fn has_items(&self) -> bool {
169 !self.items.is_empty()
170 }
171
172 #[must_use]
174 pub fn clear_items(mut self) -> Self {
175 self.items.clear();
176 self
177 }
178
179 #[must_use]
181 pub fn from(mut self, table: impl Into<TableRef>) -> Self {
182 self.from.push(table.into());
183 self
184 }
185
186 #[must_use]
188 pub fn from_subquery(mut self, subquery: Select, alias: impl IntoIden) -> Self {
189 self.from_subquery = Some((Box::new(subquery), alias.into_iden()));
190 self
191 }
192
193 #[must_use]
195 pub fn join(
196 mut self,
197 kind: JoinType,
198 table: impl Into<TableRef>,
199 on: impl IntoCondition,
200 ) -> Self {
201 self.joins.push(Join {
202 kind,
203 table: table.into(),
204 on: on.into_condition().into_expr(),
205 });
206 self
207 }
208
209 #[must_use]
211 pub fn inner_join(self, table: impl Into<TableRef>, on: impl IntoCondition) -> Self {
212 self.join(JoinType::Inner, table, on)
213 }
214
215 #[must_use]
217 pub fn left_join(self, table: impl Into<TableRef>, on: impl IntoCondition) -> Self {
218 self.join(JoinType::Left, table, on)
219 }
220
221 #[must_use]
223 pub fn and_where(mut self, cond: impl IntoCondition) -> Self {
224 self.r#where = std::mem::take(&mut self.r#where).add(cond);
225 self
226 }
227
228 #[must_use]
230 pub fn cond_where(mut self, cond: impl IntoCondition) -> Self {
231 self.r#where = cond.into_condition();
232 self
233 }
234
235 #[must_use]
237 pub fn group_by(mut self, expr: Expr) -> Self {
238 self.group_by.push(expr);
239 self
240 }
241
242 #[must_use]
244 pub fn and_having(mut self, cond: impl IntoCondition) -> Self {
245 self.having = std::mem::take(&mut self.having).add(cond);
246 self
247 }
248
249 #[must_use]
251 pub fn order_by(mut self, column: impl Into<ColumnRef>, order: Order) -> Self {
252 self.order_by.push((Expr::Column(column.into()), order));
253 self
254 }
255
256 #[must_use]
258 pub fn order_by_expr(mut self, expr: Expr, order: Order) -> Self {
259 self.order_by.push((expr, order));
260 self
261 }
262
263 #[must_use]
265 pub fn clear_order_by(mut self) -> Self {
266 self.order_by.clear();
267 self
268 }
269
270 #[must_use]
272 pub fn limit(mut self, limit: u64) -> Self {
273 self.limit = Some(limit);
274 self
275 }
276
277 #[must_use]
279 pub fn reset_limit(mut self) -> Self {
280 self.limit = None;
281 self
282 }
283
284 #[must_use]
286 pub fn offset(mut self, offset: u64) -> Self {
287 self.offset = Some(offset);
288 self
289 }
290
291 #[must_use]
293 pub fn reset_offset(mut self) -> Self {
294 self.offset = None;
295 self
296 }
297
298 pub fn from_tables(&self) -> &[TableRef] {
300 &self.from
301 }
302
303 pub fn joins(&self) -> &[Join] {
305 &self.joins
306 }
307}
308
309#[derive(Clone, Debug, PartialEq)]
311pub struct OnConflict {
312 pub(crate) target: Vec<Ident>,
314 pub(crate) action: ConflictAction,
316}
317
318#[derive(Clone, Debug, PartialEq)]
320pub(crate) enum ConflictAction {
321 Nothing,
323 Update(Vec<(Ident, Expr)>),
325}
326
327impl OnConflict {
328 pub fn do_nothing<C: IntoIden>(columns: impl IntoIterator<Item = C>) -> Self {
330 Self {
331 target: columns.into_iter().map(IntoIden::into_iden).collect(),
332 action: ConflictAction::Nothing,
333 }
334 }
335
336 pub fn update_columns<C: IntoIden, U: IntoIden>(
339 columns: impl IntoIterator<Item = C>,
340 update: impl IntoIterator<Item = U>,
341 ) -> Self {
342 let sets = update
343 .into_iter()
344 .map(|c| {
345 let c = c.into_iden();
346 let excluded =
347 Expr::Column(ColumnRef::TableColumn("excluded".into_iden(), c.clone()));
348 (c, excluded)
349 })
350 .collect();
351 Self {
352 target: columns.into_iter().map(IntoIden::into_iden).collect(),
353 action: ConflictAction::Update(sets),
354 }
355 }
356
357 pub fn update_exprs<C: IntoIden, U: IntoIden>(
359 columns: impl IntoIterator<Item = C>,
360 sets: impl IntoIterator<Item = (U, Expr)>,
361 ) -> Self {
362 Self {
363 target: columns.into_iter().map(IntoIden::into_iden).collect(),
364 action: ConflictAction::Update(
365 sets.into_iter().map(|(c, e)| (c.into_iden(), e)).collect(),
366 ),
367 }
368 }
369}
370
371#[derive(Clone, Debug, Default, PartialEq)]
373pub struct Insert {
374 pub(crate) table: Option<TableRef>,
376 pub(crate) columns: Vec<Ident>,
378 pub(crate) rows: Vec<Vec<Expr>>,
380 pub(crate) default_values: bool,
382 pub(crate) on_conflict: Option<OnConflict>,
384 pub(crate) returning: Returning,
386 pub(crate) select: Option<Box<Select>>,
388}
389
390impl Insert {
391 #[must_use]
393 pub fn into_table(mut self, table: impl Into<TableRef>) -> Self {
394 self.table = Some(table.into());
395 self
396 }
397
398 #[must_use]
400 pub fn columns<C: IntoIden>(mut self, columns: impl IntoIterator<Item = C>) -> Self {
401 self.columns = columns.into_iter().map(IntoIden::into_iden).collect();
402 self
403 }
404
405 #[must_use]
407 pub fn values<V: Into<Expr>>(mut self, row: impl IntoIterator<Item = V>) -> Self {
408 self.rows.push(row.into_iter().map(Into::into).collect());
409 self
410 }
411
412 #[must_use]
414 pub fn default_values(mut self) -> Self {
415 self.default_values = true;
416 self
417 }
418
419 #[must_use]
421 pub fn select_from(mut self, select: Select) -> Self {
422 self.select = Some(Box::new(select));
423 self
424 }
425
426 #[must_use]
428 pub fn on_conflict(mut self, on_conflict: OnConflict) -> Self {
429 self.on_conflict = Some(on_conflict);
430 self
431 }
432
433 #[must_use]
435 pub fn returning(mut self, returning: Returning) -> Self {
436 self.returning = returning;
437 self
438 }
439
440 #[must_use]
442 pub fn returning_all(self) -> Self {
443 self.returning(Returning::All)
444 }
445
446 pub fn row_count(&self) -> usize {
448 self.rows.len()
449 }
450}
451
452#[derive(Clone, Debug, Default, PartialEq)]
454pub struct Update {
455 pub(crate) table: Option<TableRef>,
457 pub(crate) sets: Vec<(Ident, Expr)>,
459 pub(crate) r#where: Option<Condition>,
461 pub(crate) returning: Returning,
463 pub(crate) limit: Option<u64>,
465}
466
467impl Update {
468 #[must_use]
470 pub fn table(mut self, table: impl Into<TableRef>) -> Self {
471 self.table = Some(table.into());
472 self
473 }
474
475 #[must_use]
477 pub fn value(mut self, column: impl IntoIden, value: impl Into<Expr>) -> Self {
478 self.sets.push((column.into_iden(), value.into()));
479 self
480 }
481
482 #[must_use]
484 pub fn values<C: IntoIden, V: Into<Expr>>(
485 mut self,
486 sets: impl IntoIterator<Item = (C, V)>,
487 ) -> Self {
488 for (c, v) in sets {
489 self = self.value(c, v);
490 }
491 self
492 }
493
494 #[must_use]
496 pub fn and_where(mut self, cond: impl IntoCondition) -> Self {
497 let current = self.r#where.take().unwrap_or_else(Condition::all);
498 self.r#where = Some(current.add(cond));
499 self
500 }
501
502 #[must_use]
504 pub fn returning(mut self, returning: Returning) -> Self {
505 self.returning = returning;
506 self
507 }
508
509 #[must_use]
511 pub fn returning_all(self) -> Self {
512 self.returning(Returning::All)
513 }
514
515 pub fn has_sets(&self) -> bool {
517 !self.sets.is_empty()
518 }
519}
520
521#[derive(Clone, Debug, Default, PartialEq)]
523pub struct Delete {
524 pub(crate) table: Option<TableRef>,
526 pub(crate) r#where: Option<Condition>,
528 pub(crate) returning: Returning,
530}
531
532impl Delete {
533 #[must_use]
535 pub fn from_table(mut self, table: impl Into<TableRef>) -> Self {
536 self.table = Some(table.into());
537 self
538 }
539
540 #[must_use]
542 pub fn and_where(mut self, cond: impl IntoCondition) -> Self {
543 let current = self.r#where.take().unwrap_or_else(Condition::all);
544 self.r#where = Some(current.add(cond));
545 self
546 }
547
548 #[must_use]
550 pub fn returning(mut self, returning: Returning) -> Self {
551 self.returning = returning;
552 self
553 }
554}
555
556impl From<Value> for SelectItem {
557 fn from(v: Value) -> Self {
558 SelectItem::Expr(Expr::Value(v))
559 }
560}