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::{QuerySink, 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>(wheres: &[ExprKind]) -> QuerySink<D> {
20    let mut sink = QuerySink::<D>::new();
21    sink.text("DELETE FROM ");
22    render_ident::<D>(&mut sink, T::NAME);
23
24    render_and_list::<D>(&mut sink, " WHERE ", wheres);
25
26    sink
27}
28
29pub struct Delete<D, T: Table> {
30    wheres: Vec<ExprKind>,
31    _marker: PhantomData<fn() -> (D, T)>,
32}
33
34impl<D, T: Table> Delete<D, T> {
35    /// A correlated subquery over the table this statement writes — the
36    /// same `EXISTS` a `SELECT` builds with `Select::correlated`, against
37    /// the one-table scope a write statement has.
38    pub fn correlated<S, InnerSel>(
39        &self,
40        source: S,
41        selection: InnerSel,
42    ) -> crate::select::Select<
43        D,
44        crate::scope::Cons<
45            crate::scope::TableSlot<S::Table, crate::scope::NotNull>,
46            WrittenTable<T>,
47        >,
48        InnerSel,
49        WrittenTable<T>,
50    >
51    where
52        S: crate::select::JoinSource<D>,
53    {
54        crate::select::correlated_with(source, selection)
55    }
56
57    pub fn filter<C: Condition<D, WrittenTable<T>, Idxs>, Idxs>(mut self, cond: C) -> Self {
58        self.wheres.push(cond.into_predicate().into_kind());
59        self
60    }
61
62    /// AND-folds a runtime-length collection of discharged conditions, the
63    /// same way `Select::filter_all` does.
64    pub fn filter_all(
65        mut self,
66        conds: impl IntoIterator<Item = Predicate<D, WrittenTable<T>>>,
67    ) -> Self {
68        self.wheres
69            .extend(conds.into_iter().map(Predicate::into_kind));
70        self
71    }
72}
73
74impl<D: Dialect, T: Table> crate::statement::private::Sealed for Delete<D, T> {}
75
76impl<D: Dialect, T: Table> Statement for Delete<D, T> {
77    type Dialect = D;
78    type Table = T;
79    fn render(&self) -> QuerySink<D> {
80        render_delete::<D, T>(&self.wheres)
81    }
82}