keelson_mysql/statement/
delete.rs1use std::borrow::Cow;
2
3use keelson_core::clause::{
4 HasJoins, HasLimit, HasOrderBy, HasTableRef, HasWhere, HasWith, Join, Limit, OrderBy, TableRef,
5 Where, With,
6};
7use keelson_core::expr::{Expr, IntoExpr, IntoExprList};
8use keelson_core::{Dialect, Error, Expression, Mod, Query, QueryExtensions, QueryType, SqlWriter};
9
10use super::{HasDeleteTables, HasExtraTables, write_hints_and_modifiers, write_table_list};
11use crate::Mysql;
12use crate::extras::{HasHints, HasModifiers, Hints, Modifiers};
13
14#[derive(Debug, Clone, Default)]
45pub struct DeleteQuery {
46 pub with: With,
48 pub hints: Hints,
50 pub modifiers: Modifiers,
52 pub tables: Vec<TableRef>,
54 pub partitions: Vec<Cow<'static, str>>,
56 pub using: TableRef,
58 pub extra_using: Vec<TableRef>,
60 pub where_: Where,
62 pub order_by: OrderBy,
64 pub limit: Limit,
66}
67
68impl DeleteQuery {
69 pub fn new() -> DeleteQuery {
71 DeleteQuery::default()
72 }
73
74 pub fn apply(&mut self, mods: impl Mod<DeleteQuery>) {
76 mods.apply(self);
77 }
78}
79
80impl Expression for DeleteQuery {
81 fn write_sql(&self, w: &mut SqlWriter<'_>) {
82 w.write_if(!self.with.is_empty(), "", &self.with, " ");
83
84 let mut tables = self.tables.iter().filter(|t| !t.is_empty());
85 let Some(first) = tables.next() else {
86 w.record_error(Error::Incomplete("the table of a DELETE"));
87 return;
88 };
89
90 w.push_str("DELETE ");
91 write_hints_and_modifiers(w, &self.hints, &self.modifiers);
92 w.push_str("FROM ");
93 w.write_expr(first);
94 for table in tables {
95 w.push_str(", ");
96 w.write_expr(table);
97 }
98
99 if !self.partitions.is_empty() {
100 w.push_str(" PARTITION (");
101 for (i, partition) in self.partitions.iter().enumerate() {
102 if i > 0 {
103 w.push_str(", ");
104 }
105 w.push_quoted(&[partition]);
106 }
107 w.push_str(")");
108 }
109
110 write_table_list(
111 w,
112 " USING ",
113 &self.using,
114 &self.extra_using,
115 "the USING item its joins attach to",
116 );
117
118 w.write_if(!self.where_.is_empty(), " ", &self.where_, "");
119 w.write_if(!self.order_by.is_empty(), " ", &self.order_by, "");
120 w.write_if(!self.limit.is_empty(), " ", &self.limit, "");
121 }
122}
123
124impl Query for DeleteQuery {
125 fn query_type(&self) -> QueryType {
126 QueryType::Delete
127 }
128
129 fn dialect(&self) -> &dyn Dialect {
130 &Mysql
131 }
132}
133
134impl<H, L, M> QueryExtensions<H, L, M> for DeleteQuery {}
135
136impl IntoExpr for DeleteQuery {
137 fn into_expr(self) -> Expr {
138 crate::query(self)
139 }
140}
141
142impl IntoExprList for DeleteQuery {
143 fn into_expr_list(self) -> Vec<Expr> {
144 vec![self.into_expr()]
145 }
146}
147
148impl HasWith for DeleteQuery {
149 fn with_mut(&mut self) -> &mut With {
150 &mut self.with
151 }
152}
153
154impl HasHints for DeleteQuery {
155 fn hints_mut(&mut self) -> &mut Hints {
156 &mut self.hints
157 }
158}
159
160impl HasModifiers for DeleteQuery {
161 fn modifiers_mut(&mut self) -> &mut Modifiers {
162 &mut self.modifiers
163 }
164}
165
166impl HasDeleteTables for DeleteQuery {
167 fn delete_tables_mut(&mut self) -> &mut Vec<TableRef> {
168 &mut self.tables
169 }
170
171 fn delete_partitions_mut(&mut self) -> &mut Vec<Cow<'static, str>> {
172 &mut self.partitions
173 }
174}
175
176impl HasTableRef for DeleteQuery {
177 fn table_ref_mut(&mut self) -> &mut TableRef {
178 &mut self.using
179 }
180}
181
182impl HasExtraTables for DeleteQuery {
183 fn extra_tables_mut(&mut self) -> &mut Vec<TableRef> {
184 &mut self.extra_using
185 }
186}
187
188impl HasJoins for DeleteQuery {
189 fn joins_mut(&mut self) -> &mut Vec<Join> {
190 &mut self.using.joins
191 }
192}
193
194impl HasWhere for DeleteQuery {
195 fn where_mut(&mut self) -> &mut Where {
196 &mut self.where_
197 }
198}
199
200impl HasOrderBy for DeleteQuery {
201 fn order_by_mut(&mut self) -> &mut OrderBy {
202 &mut self.order_by
203 }
204}
205
206impl HasLimit for DeleteQuery {
207 fn limit_mut(&mut self) -> &mut Limit {
208 &mut self.limit
209 }
210}