1use crate::args::Args;
4use crate::cond::{ArgsRef, Cond};
5use crate::cte::CTEBuilder;
6use crate::flavor::Flavor;
7use crate::injection::{Injection, InjectionMarker};
8use crate::modifiers::{Arg, Builder};
9use crate::string_builder::StringBuilder;
10use crate::where_clause::{WhereClause, WhereClauseBuilder, WhereClauseRef};
11use std::cell::RefCell;
12use std::ops::Deref;
13use std::rc::Rc;
14
15const DELETE_MARKER_INIT: InjectionMarker = 0;
16const DELETE_MARKER_AFTER_WITH: InjectionMarker = 1;
17const DELETE_MARKER_AFTER_DELETE_FROM: InjectionMarker = 2;
18const DELETE_MARKER_AFTER_WHERE: InjectionMarker = 3;
19const DELETE_MARKER_AFTER_ORDER_BY: InjectionMarker = 4;
20const DELETE_MARKER_AFTER_LIMIT: InjectionMarker = 5;
21const DELETE_MARKER_AFTER_RETURNING: InjectionMarker = 6;
22
23#[derive(Debug)]
24pub struct DeleteBuilder {
25 args: ArgsRef,
26 cond: Cond,
27
28 tables: Vec<String>,
29
30 where_clause: Option<WhereClauseRef>,
31 where_var: Option<String>,
32 cte_var: Option<String>,
33 cte: Option<CTEBuilder>,
34
35 order_by_cols: Vec<String>,
36 order: Option<&'static str>,
37 limit_var: Option<String>,
38 returning: Vec<String>,
39
40 injection: Injection,
41 marker: InjectionMarker,
42}
43
44impl Deref for DeleteBuilder {
45 type Target = Cond;
46 fn deref(&self) -> &Self::Target {
47 &self.cond
48 }
49}
50
51impl Default for DeleteBuilder {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl Clone for DeleteBuilder {
58 fn clone(&self) -> Self {
59 self.clone_builder()
60 }
61}
62
63impl DeleteBuilder {
64 pub fn new() -> Self {
65 let args = Rc::new(RefCell::new(Args::default()));
66 let cond = Cond::with_args(args.clone());
67 Self {
68 args,
69 cond,
70 tables: Vec::new(),
71 where_clause: None,
72 where_var: None,
73 order_by_cols: Vec::new(),
74 order: None,
75 limit_var: None,
76 returning: Vec::new(),
77 cte_var: None,
78 cte: None,
79 injection: Injection::new(),
80 marker: DELETE_MARKER_INIT,
81 }
82 }
83
84 pub fn set_flavor(&mut self, flavor: Flavor) -> Flavor {
85 let mut a = self.args.borrow_mut();
86 let old = a.flavor;
87 a.flavor = flavor;
88 old
89 }
90
91 pub fn flavor(&self) -> Flavor {
92 self.args.borrow().flavor
93 }
94
95 fn table_names(&self) -> Vec<String> {
96 let mut table_names = Vec::new();
97 if !self.tables.is_empty() {
98 table_names.extend(self.tables.clone());
99 }
100 if let Some(cte) = &self.cte {
101 table_names.extend(cte.table_names_for_from());
102 }
103 table_names
104 }
105
106 pub fn with(&mut self, cte: &CTEBuilder) -> &mut Self {
107 let cte_clone = cte.clone();
108 let ph = self.var(Arg::Builder(Box::new(cte.clone())));
109 self.cte = Some(cte_clone);
110 self.cte_var = Some(ph);
111 self.marker = DELETE_MARKER_AFTER_WITH;
112 self
113 }
114
115 pub fn where_clause(&self) -> Option<WhereClauseRef> {
116 self.where_clause.clone()
117 }
118
119 pub fn set_where_clause(&mut self, wc: Option<WhereClauseRef>) -> &mut Self {
120 match wc {
121 None => {
122 self.where_clause = None;
123 self.where_var = None;
124 }
125 Some(wc) => {
126 if let Some(ph) = &self.where_var {
127 self.args.borrow_mut().replace(
128 ph,
129 Arg::Builder(Box::new(WhereClauseBuilder::new(wc.clone()))),
130 );
131 } else {
132 let ph = self.var(Arg::Builder(Box::new(WhereClauseBuilder::new(wc.clone()))));
133 self.where_var = Some(ph);
134 }
135 self.where_clause = Some(wc);
136 }
137 }
138 self
139 }
140
141 pub fn clear_where_clause(&mut self) -> &mut Self {
142 self.set_where_clause(None)
143 }
144
145 pub fn clone_builder(&self) -> Self {
146 let old_args = self.args.borrow().clone();
147 let args = Rc::new(RefCell::new(old_args));
148 let cond = Cond::with_args(args.clone());
149
150 let mut cloned = Self {
151 args,
152 cond,
153 tables: self.tables.clone(),
154 where_clause: self.where_clause.clone(),
155 where_var: self.where_var.clone(),
156 cte_var: self.cte_var.clone(),
157 cte: self.cte.clone(),
158 order_by_cols: self.order_by_cols.clone(),
159 order: self.order,
160 limit_var: self.limit_var.clone(),
161 returning: self.returning.clone(),
162 injection: self.injection.clone(),
163 marker: self.marker,
164 };
165
166 if let (Some(wc), Some(ph)) = (&self.where_clause, &self.where_var) {
167 let new_wc = Rc::new(RefCell::new(wc.borrow().clone()));
168 cloned.where_clause = Some(new_wc.clone());
169 cloned
170 .args
171 .borrow_mut()
172 .replace(ph, Arg::Builder(Box::new(WhereClauseBuilder::new(new_wc))));
173 }
174
175 if let (Some(cte), Some(ph)) = (&self.cte, &self.cte_var) {
176 let cte_for_arg = cte.clone();
177 let cte_for_field = cte_for_arg.clone();
178 cloned.cte = Some(cte_for_field);
179 cloned
180 .args
181 .borrow_mut()
182 .replace(ph, Arg::Builder(Box::new(cte_for_arg)));
183 }
184
185 cloned
186 }
187
188 fn var(&self, v: impl Into<Arg>) -> String {
189 self.args.borrow_mut().add(v)
190 }
191
192 pub fn delete_from(
193 &mut self,
194 tables: impl IntoIterator<Item = impl Into<String>>,
195 ) -> &mut Self {
196 self.tables = tables.into_iter().map(Into::into).collect();
197 self.marker = DELETE_MARKER_AFTER_DELETE_FROM;
198 self
199 }
200
201 pub fn where_(&mut self, and_expr: impl IntoIterator<Item = impl Into<String>>) -> &mut Self {
202 let exprs: Vec<String> = and_expr.into_iter().map(Into::into).collect();
203 if exprs.is_empty() || exprs.iter().all(|s| s.is_empty()) {
204 return self;
205 }
206
207 if self.where_clause.is_none() {
208 let wc = WhereClause::new();
209 let ph = self.var(Arg::Builder(Box::new(WhereClauseBuilder::new(wc.clone()))));
210 self.where_clause = Some(wc);
211 self.where_var = Some(ph);
212 }
213
214 self.where_clause
215 .as_ref()
216 .unwrap()
217 .borrow_mut()
218 .add_where_expr(self.args.clone(), exprs);
219 self.marker = DELETE_MARKER_AFTER_WHERE;
220 self
221 }
222
223 pub fn add_where_expr(
224 &mut self,
225 args: ArgsRef,
226 exprs: impl IntoIterator<Item = impl Into<String>>,
227 ) -> &mut Self {
228 let exprs: Vec<String> = exprs.into_iter().map(Into::into).collect();
229 if exprs.is_empty() || exprs.iter().all(|s| s.is_empty()) {
230 return self;
231 }
232
233 if self.where_clause.is_none() {
234 let wc = WhereClause::new();
235 let ph = self.var(Arg::Builder(Box::new(WhereClauseBuilder::new(wc.clone()))));
236 self.where_clause = Some(wc);
237 self.where_var = Some(ph);
238 }
239
240 self.where_clause
241 .as_ref()
242 .unwrap()
243 .borrow_mut()
244 .add_where_expr(args, exprs);
245 self.marker = DELETE_MARKER_AFTER_WHERE;
246 self
247 }
248
249 pub fn add_where_clause(&mut self, other: &WhereClause) -> &mut Self {
250 if self.where_clause.is_none() {
251 let wc = WhereClause::new();
252 let ph = self.var(Arg::Builder(Box::new(WhereClauseBuilder::new(wc.clone()))));
253 self.where_clause = Some(wc);
254 self.where_var = Some(ph);
255 }
256 self.where_clause
257 .as_ref()
258 .unwrap()
259 .borrow_mut()
260 .add_where_clause(other);
261 self
262 }
263
264 pub fn add_where_clause_ref(&mut self, other: &WhereClauseRef) -> &mut Self {
265 if self.where_clause.is_none() {
266 let wc = WhereClause::new();
267 let ph = self.var(Arg::Builder(Box::new(WhereClauseBuilder::new(wc.clone()))));
268 self.where_clause = Some(wc);
269 self.where_var = Some(ph);
270 }
271 self.where_clause
272 .as_ref()
273 .unwrap()
274 .borrow_mut()
275 .add_where_clause(&other.borrow());
276 self
277 }
278
279 pub fn order_by(&mut self, cols: impl IntoIterator<Item = impl Into<String>>) -> &mut Self {
280 self.order_by_cols = cols.into_iter().map(Into::into).collect();
281 self.marker = DELETE_MARKER_AFTER_ORDER_BY;
282 self
283 }
284
285 pub fn order_by_asc(&mut self, col: impl Into<String>) -> &mut Self {
286 self.order_by_cols.push(format!("{} ASC", col.into()));
287 self.marker = DELETE_MARKER_AFTER_ORDER_BY;
288 self
289 }
290
291 pub fn order_by_desc(&mut self, col: impl Into<String>) -> &mut Self {
292 self.order_by_cols.push(format!("{} DESC", col.into()));
293 self.marker = DELETE_MARKER_AFTER_ORDER_BY;
294 self
295 }
296
297 pub fn asc(&mut self) -> &mut Self {
298 self.order = Some("ASC");
299 self.marker = DELETE_MARKER_AFTER_ORDER_BY;
300 self
301 }
302
303 pub fn desc(&mut self) -> &mut Self {
304 self.order = Some("DESC");
305 self.marker = DELETE_MARKER_AFTER_ORDER_BY;
306 self
307 }
308
309 pub fn limit(&mut self, limit: i64) -> &mut Self {
310 if limit < 0 {
311 self.limit_var = None;
312 return self;
313 }
314 self.limit_var = Some(self.var(limit));
315 self.marker = DELETE_MARKER_AFTER_LIMIT;
316 self
317 }
318
319 pub fn returning(&mut self, cols: impl IntoIterator<Item = impl Into<String>>) -> &mut Self {
320 self.returning = cols.into_iter().map(Into::into).collect();
321 self.marker = DELETE_MARKER_AFTER_RETURNING;
322 self
323 }
324
325 pub fn sql(&mut self, sql: impl Into<String>) -> &mut Self {
326 self.injection.sql(self.marker, sql);
327 self
328 }
329}
330
331impl Builder for DeleteBuilder {
332 fn build_with_flavor(&self, flavor: Flavor, initial_arg: &[Arg]) -> (String, Vec<Arg>) {
333 let mut buf = StringBuilder::new();
334 write_injection(&mut buf, &self.injection, DELETE_MARKER_INIT);
335
336 if let Some(ph) = &self.cte_var {
337 buf.write_leading(ph);
338 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_WITH);
339 }
340
341 let table_names = self.table_names();
342 if !table_names.is_empty() {
343 buf.write_leading("DELETE FROM");
344 buf.write_str(" ");
345 buf.write_str(&table_names.join(", "));
346 }
347 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_DELETE_FROM);
348
349 if flavor == Flavor::SQLServer && !self.returning.is_empty() {
350 buf.write_leading("OUTPUT");
351 buf.write_str(" ");
352 let prefixed: Vec<String> = self
353 .returning
354 .iter()
355 .map(|c| format!("DELETED.{c}"))
356 .collect();
357 buf.write_str(&prefixed.join(", "));
358 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_RETURNING);
359 }
360
361 if let Some(ph) = &self.where_var {
362 buf.write_leading(ph);
363 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_WHERE);
364 }
365
366 if !self.order_by_cols.is_empty() {
367 buf.write_leading("ORDER BY");
368 buf.write_str(" ");
369 buf.write_str(&self.order_by_cols.join(", "));
370 if let Some(order) = self.order {
371 buf.write_str(" ");
372 buf.write_str(order);
373 }
374 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_ORDER_BY);
375 }
376
377 if let Some(lim) = &self.limit_var {
378 buf.write_leading("LIMIT");
379 buf.write_str(" ");
380 buf.write_str(lim);
381 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_LIMIT);
382 }
383
384 if (flavor == Flavor::PostgreSQL || flavor == Flavor::SQLite) && !self.returning.is_empty()
385 {
386 buf.write_leading("RETURNING");
387 buf.write_str(" ");
388 buf.write_str(&self.returning.join(", "));
389 write_injection(&mut buf, &self.injection, DELETE_MARKER_AFTER_RETURNING);
390 }
391
392 self.args
393 .borrow()
394 .compile_with_flavor(&buf.into_string(), flavor, initial_arg)
395 }
396
397 fn flavor(&self) -> Flavor {
398 self.flavor()
399 }
400}
401
402fn write_injection(buf: &mut StringBuilder, inj: &Injection, marker: InjectionMarker) {
403 let sqls = inj.at(marker);
404 if sqls.is_empty() {
405 return;
406 }
407 buf.write_leading("");
408 buf.write_str(&sqls.join(" "));
409}