diesel/query_builder/delete_statement/
mod.rs1use crate::backend::DieselReserveSpecialization;
2use crate::dsl::{Filter, IntoBoxed, OrFilter};
3use crate::expression::{AppearsOnTable, Expression, SelectableExpression};
4use crate::query_builder::returning::{
5 DeleteStmt, NoReturningClause, ReturningClause, ReturningQuerySource,
6};
7use crate::query_builder::where_clause::*;
8use crate::query_builder::*;
9use crate::query_dsl::RunQueryDsl;
10use crate::query_dsl::methods::{BoxedDsl, FilterDsl, OrFilterDsl};
11use crate::query_source::{QuerySource, Table};
12
13#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
14pub struct DeleteStatement<T: QuerySource, U, Ret = NoReturningClause> {
25 from_clause: FromClause<T>,
26 where_clause: U,
27 returning: Ret,
28}
29
30impl<T, U, Ret> Clone for DeleteStatement<T, U, Ret>
31where
32 T: QuerySource,
33 FromClause<T>: Clone,
34 U: Clone,
35 Ret: Clone,
36{
37 fn clone(&self) -> Self {
38 Self {
39 from_clause: self.from_clause.clone(),
40 where_clause: self.where_clause.clone(),
41 returning: self.returning.clone(),
42 }
43 }
44}
45
46impl<T, U, Ret> core::fmt::Debug for DeleteStatement<T, U, Ret>
47where
48 T: QuerySource,
49 FromClause<T>: core::fmt::Debug,
50 U: core::fmt::Debug,
51 Ret: core::fmt::Debug,
52{
53 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54 f.debug_struct("DeleteStatement")
55 .field("from_clause", &self.from_clause)
56 .field("where_clause", &self.where_clause)
57 .field("returning", &self.returning)
58 .finish()
59 }
60}
61
62impl<T, U, Ret> QueryId for DeleteStatement<T, U, Ret>
63where
64 T: QuerySource + QueryId + 'static,
65 U: QueryId,
66 Ret: QueryId,
67{
68 type QueryId = DeleteStatement<T, U::QueryId, Ret::QueryId>;
69
70 const HAS_STATIC_QUERY_ID: bool =
71 T::HAS_STATIC_QUERY_ID && U::HAS_STATIC_QUERY_ID && Ret::HAS_STATIC_QUERY_ID;
72}
73
74pub type BoxedDeleteStatement<'a, DB, T, Ret = NoReturningClause> =
76 DeleteStatement<T, BoxedWhereClause<'a, DB>, Ret>;
77
78impl<T: QuerySource, U> DeleteStatement<T, U, NoReturningClause> {
79 pub(crate) fn new(table: T, where_clause: U) -> Self {
80 DeleteStatement {
81 from_clause: FromClause::new(table),
82 where_clause,
83 returning: NoReturningClause,
84 }
85 }
86
87 pub fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>
114 where
115 Self: FilterDsl<Predicate>,
116 {
117 FilterDsl::filter(self, predicate)
118 }
119
120 pub fn or_filter<Predicate>(self, predicate: Predicate) -> OrFilter<Self, Predicate>
147 where
148 Self: OrFilterDsl<Predicate>,
149 {
150 OrFilterDsl::or_filter(self, predicate)
151 }
152
153 pub fn into_boxed<'a, DB>(self) -> IntoBoxed<'a, Self, DB>
196 where
197 DB: Backend,
198 Self: BoxedDsl<'a, DB>,
199 {
200 BoxedDsl::internal_into_boxed(self)
201 }
202}
203
204impl<T, U, Ret, Predicate> FilterDsl<Predicate> for DeleteStatement<T, U, Ret>
205where
206 U: WhereAnd<Predicate>,
207 Predicate: AppearsOnTable<T>,
208 T: QuerySource,
209{
210 type Output = DeleteStatement<T, U::Output, Ret>;
211
212 fn filter(self, predicate: Predicate) -> Self::Output {
213 DeleteStatement {
214 from_clause: self.from_clause,
215 where_clause: self.where_clause.and(predicate),
216 returning: self.returning,
217 }
218 }
219}
220
221impl<T, U, Ret, Predicate> OrFilterDsl<Predicate> for DeleteStatement<T, U, Ret>
222where
223 T: QuerySource,
224 U: WhereOr<Predicate>,
225 Predicate: AppearsOnTable<T>,
226{
227 type Output = DeleteStatement<T, U::Output, Ret>;
228
229 fn or_filter(self, predicate: Predicate) -> Self::Output {
230 DeleteStatement {
231 from_clause: self.from_clause,
232 where_clause: self.where_clause.or(predicate),
233 returning: self.returning,
234 }
235 }
236}
237
238impl<'a, T, U, Ret, DB> BoxedDsl<'a, DB> for DeleteStatement<T, U, Ret>
239where
240 U: Into<BoxedWhereClause<'a, DB>>,
241 T: QuerySource,
242{
243 type Output = BoxedDeleteStatement<'a, DB, T, Ret>;
244
245 fn internal_into_boxed(self) -> Self::Output {
246 DeleteStatement {
247 where_clause: self.where_clause.into(),
248 returning: self.returning,
249 from_clause: self.from_clause,
250 }
251 }
252}
253
254impl<T, U, Ret, DB> QueryFragment<DB> for DeleteStatement<T, U, Ret>
255where
256 DB: Backend + DieselReserveSpecialization,
257 T: Table,
258 FromClause<T>: QueryFragment<DB>,
259 U: QueryFragment<DB>,
260 Ret: QueryFragment<DB>,
261{
262 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
263 out.push_sql("DELETE");
264 self.from_clause.walk_ast(out.reborrow())?;
265 self.where_clause.walk_ast(out.reborrow())?;
266 self.returning.walk_ast(out.reborrow())?;
267 Ok(())
268 }
269}
270
271impl<T, U> AsQuery for DeleteStatement<T, U, NoReturningClause>
272where
273 T: Table,
274 DeleteStatement<T, U, ReturningClause<T::AllColumns>>: Query,
275 T::AllColumns: SelectableExpression<ReturningQuerySource<DeleteStmt, T>>,
276{
277 type SqlType = <Self::Query as Query>::SqlType;
278 type Query = DeleteStatement<T, U, ReturningClause<T::AllColumns>>;
279
280 fn as_query(self) -> Self::Query {
281 self.returning(T::all_columns())
282 }
283}
284
285impl<T, U, Ret> Query for DeleteStatement<T, U, ReturningClause<Ret>>
286where
287 T: Table,
288 Ret: SelectableExpression<ReturningQuerySource<DeleteStmt, T>>,
289{
290 type SqlType = <Ret as Expression>::SqlType;
291}
292
293impl<T, U, Ret, Conn> RunQueryDsl<Conn> for DeleteStatement<T, U, Ret> where T: QuerySource {}
294
295impl<T: QuerySource, U> DeleteStatement<T, U, NoReturningClause> {
296 pub fn returning<E>(self, returns: E) -> DeleteStatement<T, U, ReturningClause<E>>
318 where
319 DeleteStatement<T, U, ReturningClause<E>>: Query,
320 {
321 DeleteStatement {
322 where_clause: self.where_clause,
323 from_clause: self.from_clause,
324 returning: ReturningClause(returns),
325 }
326 }
327}