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