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