sea_orm/executor/
delete.rs1use crate::{
2 error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, DeleteMany, DeleteOne, EntityTrait,
3 Iterable,
4};
5use sea_query::{DeleteStatement, Query};
6use std::future::Future;
7
8use super::{SelectModel, SelectorRaw};
9
10#[derive(Clone, Debug)]
12pub struct Deleter {
13 query: DeleteStatement,
14}
15
16#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct DeleteResult {
19 pub rows_affected: u64,
21}
22
23impl<'a, A: 'a> DeleteOne<A>
24where
25 A: ActiveModelTrait,
26{
27 pub fn exec<C>(self, db: &'a C) -> impl Future<Output = Result<DeleteResult, DbErr>> + 'a
29 where
30 C: ConnectionTrait,
31 {
32 exec_delete_only(self.query, db)
34 }
35
36 pub fn exec_with_returning<C>(
42 self,
43 db: &'a C,
44 ) -> impl Future<Output = Result<Option<<A::Entity as EntityTrait>::Model>, DbErr>> + 'a
45 where
46 C: ConnectionTrait,
47 {
48 exec_delete_with_returning_one::<A::Entity, _>(self.query, db)
49 }
50}
51
52impl<'a, E> DeleteMany<E>
53where
54 E: EntityTrait,
55{
56 pub fn exec<C>(self, db: &'a C) -> impl Future<Output = Result<DeleteResult, DbErr>> + 'a
58 where
59 C: ConnectionTrait,
60 {
61 exec_delete_only(self.query, db)
63 }
64
65 pub fn exec_with_returning<C>(
71 self,
72 db: &C,
73 ) -> impl Future<Output = Result<Vec<E::Model>, DbErr>> + '_
74 where
75 E: EntityTrait,
76 C: ConnectionTrait,
77 {
78 exec_delete_with_returning_many::<E, _>(self.query, db)
79 }
80}
81
82impl Deleter {
83 pub fn new(query: DeleteStatement) -> Self {
85 Self { query }
86 }
87
88 pub fn exec<C>(self, db: &C) -> impl Future<Output = Result<DeleteResult, DbErr>> + '_
90 where
91 C: ConnectionTrait,
92 {
93 exec_delete(self.query, db)
94 }
95
96 pub fn exec_with_returning<E, C>(
102 self,
103 db: &C,
104 ) -> impl Future<Output = Result<Vec<E::Model>, DbErr>> + '_
105 where
106 E: EntityTrait,
107 C: ConnectionTrait,
108 {
109 exec_delete_with_returning_many::<E, _>(self.query, db)
110 }
111}
112
113async fn exec_delete_only<C>(query: DeleteStatement, db: &C) -> Result<DeleteResult, DbErr>
114where
115 C: ConnectionTrait,
116{
117 Deleter::new(query).exec(db).await
118}
119
120async fn exec_delete<C>(query: DeleteStatement, db: &C) -> Result<DeleteResult, DbErr>
121where
122 C: ConnectionTrait,
123{
124 let builder = db.get_database_backend();
125 let statement = builder.build(&query);
126
127 let result = db.execute(statement).await?;
128 Ok(DeleteResult {
129 rows_affected: result.rows_affected(),
130 })
131}
132
133async fn exec_delete_with_returning_one<E, C>(
134 mut query: DeleteStatement,
135 db: &C,
136) -> Result<Option<E::Model>, DbErr>
137where
138 E: EntityTrait,
139 C: ConnectionTrait,
140{
141 let models = match db.support_returning() {
142 true => {
143 let db_backend = db.get_database_backend();
144 let delete_statement = db_backend.build(&query.returning_all().to_owned());
145 SelectorRaw::<SelectModel<<E>::Model>>::from_statement(delete_statement)
146 .one(db)
147 .await?
148 }
149 false => unimplemented!("Database backend doesn't support RETURNING"),
150 };
151 Ok(models)
152}
153
154async fn exec_delete_with_returning_many<E, C>(
155 mut query: DeleteStatement,
156 db: &C,
157) -> Result<Vec<E::Model>, DbErr>
158where
159 E: EntityTrait,
160 C: ConnectionTrait,
161{
162 let models = match db.support_returning() {
163 true => {
164 let db_backend = db.get_database_backend();
165 let returning = Query::returning().exprs(
166 E::Column::iter().map(|c| c.select_enum_as(c.into_returning_expr(db_backend))),
167 );
168 let query = query.returning(returning);
169 let delete_statement = db_backend.build(&query.to_owned());
170 SelectorRaw::<SelectModel<<E>::Model>>::from_statement(delete_statement)
171 .all(db)
172 .await?
173 }
174 false => unimplemented!("Database backend doesn't support RETURNING"),
175 };
176 Ok(models)
177}