Skip to main content

qbrs_core/
delete.rs

1//! `DELETE FROM .. WHERE ..`.
2
3use std::marker::PhantomData;
4
5use crate::dialect::Dialect;
6use crate::expr::ExprKind;
7use crate::render::{Sink, render_and_list, render_ident};
8use crate::scope::{BaseTable, Table};
9use crate::select::{Condition, Predicate};
10use crate::statement::{Statement, WrittenTable};
11
12pub fn delete<D, T: BaseTable>(_table: T) -> Delete<D, T> {
13    Delete {
14        wheres: Vec::new(),
15        _marker: PhantomData,
16    }
17}
18
19fn render_delete<D: Dialect, T: Table>(sink: &mut dyn Sink, wheres: &[ExprKind]) {
20    sink.text("DELETE FROM ");
21    render_ident::<D>(sink, T::NAME);
22    render_and_list::<D>(sink, " WHERE ", wheres);
23}
24
25pub struct Delete<D, T: Table> {
26    wheres: Vec<ExprKind>,
27    _marker: PhantomData<fn() -> (D, T)>,
28}
29
30impl<D, T: Table> Delete<D, T> {
31    /// A correlated subquery over the table this statement writes. It is
32    /// the same `EXISTS` a `SELECT` builds with `Select::correlated`,
33    /// against the one-table scope a write statement has.
34    pub fn correlated<S, InnerSel>(
35        &self,
36        source: S,
37        selection: InnerSel,
38    ) -> crate::select::Select<
39        D,
40        crate::scope::Cons<
41            crate::scope::TableSlot<S::Table, crate::scope::NotNull>,
42            WrittenTable<T>,
43        >,
44        InnerSel,
45        WrittenTable<T>,
46    >
47    where
48        S: crate::select::JoinSource<D>,
49    {
50        crate::select::correlated_with(source, selection)
51    }
52
53    pub fn filter<C: Condition<D, WrittenTable<T>, Idxs>, Idxs>(mut self, cond: C) -> Self {
54        self.wheres.push(cond.into_predicate().into_kind());
55        self
56    }
57
58    /// AND-folds a runtime-length collection of discharged conditions, the
59    /// same way `Select::filter_all` does.
60    pub fn filter_all(
61        mut self,
62        conds: impl IntoIterator<Item = Predicate<D, WrittenTable<T>>>,
63    ) -> Self {
64        self.wheres
65            .extend(conds.into_iter().map(Predicate::into_kind));
66        self
67    }
68}
69
70impl<D: Dialect, T: Table> crate::statement::private::Sealed for Delete<D, T> {}
71
72impl<D: Dialect, T: Table> Statement for Delete<D, T> {
73    type Dialect = D;
74    type Table = T;
75    fn render_into(&self, sink: &mut dyn Sink) {
76        render_delete::<D, T>(sink, &self.wheres);
77    }
78}