1use crate::{
2 ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, IntoActiveModel, Iterable,
3 PrimaryKeyToColumn, QueryFilter, QueryTrait,
4};
5use core::marker::PhantomData;
6use sea_query::DeleteStatement;
7
8#[derive(Clone, Debug)]
10pub struct Delete;
11
12#[derive(Clone, Debug)]
14pub struct DeleteOne<A>
15where
16 A: ActiveModelTrait,
17{
18 pub(crate) query: DeleteStatement,
19 pub(crate) model: A,
20}
21
22#[derive(Clone, Debug)]
24pub struct DeleteMany<E>
25where
26 E: EntityTrait,
27{
28 pub(crate) query: DeleteStatement,
29 pub(crate) entity: PhantomData<E>,
30}
31
32impl Delete {
33 pub fn one<E, A, M>(model: M) -> DeleteOne<A>
64 where
65 E: EntityTrait,
66 A: ActiveModelTrait<Entity = E>,
67 M: IntoActiveModel<A>,
68 {
69 let myself = DeleteOne {
70 query: DeleteStatement::new()
71 .from_table(A::Entity::default().table_ref())
72 .to_owned(),
73 model: model.into_active_model(),
74 };
75 myself.prepare()
76 }
77
78 pub fn many<E>(entity: E) -> DeleteMany<E>
92 where
93 E: EntityTrait,
94 {
95 DeleteMany {
96 query: DeleteStatement::new()
97 .from_table(entity.table_ref())
98 .to_owned(),
99 entity: PhantomData,
100 }
101 }
102}
103
104impl<A> DeleteOne<A>
105where
106 A: ActiveModelTrait,
107{
108 pub(crate) fn prepare(mut self) -> Self {
109 for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {
110 let col = key.into_column();
111 let av = self.model.get(col);
112 match av {
113 ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {
114 self = self.filter(col.eq(value));
115 }
116 ActiveValue::NotSet => panic!("PrimaryKey is not set"),
117 }
118 }
119 self
120 }
121}
122
123impl<A> QueryFilter for DeleteOne<A>
124where
125 A: ActiveModelTrait,
126{
127 type QueryStatement = DeleteStatement;
128
129 fn query(&mut self) -> &mut DeleteStatement {
130 &mut self.query
131 }
132}
133
134impl<E> QueryFilter for DeleteMany<E>
135where
136 E: EntityTrait,
137{
138 type QueryStatement = DeleteStatement;
139
140 fn query(&mut self) -> &mut DeleteStatement {
141 &mut self.query
142 }
143}
144
145impl<A> QueryTrait for DeleteOne<A>
146where
147 A: ActiveModelTrait,
148{
149 type QueryStatement = DeleteStatement;
150
151 fn query(&mut self) -> &mut DeleteStatement {
152 &mut self.query
153 }
154
155 fn as_query(&self) -> &DeleteStatement {
156 &self.query
157 }
158
159 fn into_query(self) -> DeleteStatement {
160 self.query
161 }
162}
163
164impl<E> QueryTrait for DeleteMany<E>
165where
166 E: EntityTrait,
167{
168 type QueryStatement = DeleteStatement;
169
170 fn query(&mut self) -> &mut DeleteStatement {
171 &mut self.query
172 }
173
174 fn as_query(&self) -> &DeleteStatement {
175 &self.query
176 }
177
178 fn into_query(self) -> DeleteStatement {
179 self.query
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::tests_cfg::{cake, fruit};
186 use crate::{entity::*, query::*, DbBackend};
187
188 #[test]
189 fn delete_1() {
190 assert_eq!(
191 Delete::one(cake::Model {
192 id: 1,
193 name: "Apple Pie".to_owned(),
194 })
195 .build(DbBackend::Postgres)
196 .to_string(),
197 r#"DELETE FROM "cake" WHERE "cake"."id" = 1"#,
198 );
199 assert_eq!(
200 Delete::one(cake::ActiveModel {
201 id: ActiveValue::set(1),
202 name: ActiveValue::set("Apple Pie".to_owned()),
203 })
204 .build(DbBackend::Postgres)
205 .to_string(),
206 r#"DELETE FROM "cake" WHERE "cake"."id" = 1"#,
207 );
208 }
209
210 #[test]
211 fn delete_2() {
212 assert_eq!(
213 Delete::many(fruit::Entity)
214 .filter(fruit::Column::Name.contains("Cheese"))
215 .build(DbBackend::Postgres)
216 .to_string(),
217 r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE '%Cheese%'"#,
218 );
219 }
220}