1use 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 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 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}