chain_builder/mysql/
mod.rs1use serde_json::Value;
2
3use crate::{
5 builder::ChainBuilder,
6 common::{
7 join_compiler::join_compiler,
8 method_compiler::{method_compiler_with_provider, ToSqlProvider},
9 statement_compiler::statement_compiler,
10 },
11};
12
13struct MySqlToSqlProvider;
14
15impl ToSqlProvider for MySqlToSqlProvider {
16 fn to_sql(&self, chain_builder: &ChainBuilder) -> (String, Vec<Value>) {
17 merge_to_sql(to_sql(chain_builder))
18 }
19}
20
21#[derive(Debug, Clone, Default)]
22pub struct ToSql {
23 pub statement: (String, Vec<Value>),
24 pub method: (String, Vec<Value>),
25 pub join: (String, Vec<Value>),
26 pub raw: (String, Vec<Value>),
27 pub sql_with: (String, Vec<Value>),
28 pub sql_union: (String, Vec<Value>),
29 pub limit: Option<usize>,
30 pub offset: Option<usize>,
31 pub group_by: Vec<String>,
32 pub group_by_raw: (String, Vec<Value>),
33 pub having: (String, Vec<Value>),
34 pub order_by: Vec<String>,
35 pub order_by_raw: (String, Vec<Value>),
36}
37
38pub fn to_sql(chain_builder: &ChainBuilder) -> ToSql {
39 let mut statement = statement_compiler(chain_builder);
41 if !statement.0.is_empty() {
42 statement.0 = format!("WHERE {}", statement.0);
43 }
44 let method = method_compiler_with_provider(chain_builder, &MySqlToSqlProvider);
46 let join = join_compiler(chain_builder, true);
48
49 let mut with = String::new();
52 let mut with_binds: Vec<serde_json::Value> = vec![];
53 let mut is_first_with = true;
54 let mut sql_union = String::new();
56 let mut sql_union_binds: Vec<serde_json::Value> = vec![];
57 let mut is_first_union = true;
58 let mut limit = None;
60 let mut offset = None;
62 let mut group_by: Vec<String> = vec![];
64 let mut group_by_raw = String::new();
66 let mut group_by_raw_binds: Vec<serde_json::Value> = vec![];
67 let mut having = String::new();
69 let mut having_binds: Vec<serde_json::Value> = vec![];
70 let mut order_by: Vec<String> = vec![];
72 let mut order_by_raw = String::new();
74 let mut order_by_raw_binds: Vec<serde_json::Value> = vec![];
75
76 let client = chain_builder.query.client.clone();
78
79 for common in chain_builder.query.query_common.iter() {
80 match common {
81 crate::types::Common::With(alias, recursive, chain_builder) => {
82 with.push_str("WITH");
83 with.push(' ');
84 if !is_first_with {
85 with.push_str(", ");
86 }
87 is_first_with = false;
88 if *recursive {
89 with.push_str("RECURSIVE");
90 with.push(' ');
91 }
92 with.push_str(&crate::dialect::escape_identifier(alias, &client));
93 with.push_str(" AS (");
94 let sql = merge_to_sql(to_sql(chain_builder));
95 with.push_str(sql.0.as_str());
96 with.push(')');
97 with_binds.extend(sql.1);
98 with.push(' ');
99 }
100 crate::types::Common::Union(is_all, chain_builder) => {
101 if !is_first_union {
102 sql_union.push(' ');
103 }
104 is_first_union = false;
105 if *is_all {
106 sql_union.push_str("UNION ALL");
107 } else {
108 sql_union.push_str("UNION");
109 }
110 sql_union.push(' ');
111 let sql = merge_to_sql(to_sql(chain_builder));
112 sql_union.push_str(sql.0.as_str());
113 sql_union_binds.extend(sql.1);
114 }
115 crate::types::Common::Limit(l) => {
116 limit = Some(*l);
117 }
118 crate::types::Common::Offset(o) => {
119 offset = Some(*o);
120 }
121 crate::types::Common::GroupBy(g) => {
122 group_by.extend(
123 g.iter()
124 .map(|col| crate::dialect::escape_identifier(col, &client)),
125 );
126 }
127 crate::types::Common::GroupByRaw(g, b) => {
128 group_by_raw.push_str(g.as_str());
129 if let Some(b) = b {
130 group_by_raw_binds.extend(b.clone());
131 }
132 }
133 crate::types::Common::OrderBy(column, order) => {
134 order_by.push(format!(
135 "{} {}",
136 crate::dialect::escape_identifier(column, &client),
137 order
138 ));
139 }
140 crate::types::Common::OrderByRaw(sql, val) => {
141 order_by_raw.push_str(sql.as_str());
142 if let Some(val) = val {
143 order_by_raw_binds.extend(val.clone());
144 }
145 }
146 crate::types::Common::Having(sql, val) => {
147 if !having.is_empty() {
148 having.push_str(" AND ");
149 }
150 having.push_str(sql);
151 if let Some(val) = val {
152 having_binds.extend(val.clone());
153 }
154 }
155 }
156 }
157
158 let mut raw_sql = String::new();
160 let mut raw_binds: Vec<serde_json::Value> = vec![];
161 if !chain_builder.query.raw.is_empty() {
162 for (i, raw) in chain_builder.query.raw.iter().enumerate() {
163 if i > 0 {
164 raw_sql.push(' ');
165 }
166 raw_sql.push_str(&raw.0);
167 if let Some(binds) = &raw.1 {
168 raw_binds.extend(binds.clone());
169 }
170 }
171 }
172
173 ToSql {
174 statement,
175 method,
176 join,
177 raw: (raw_sql, raw_binds),
178 sql_with: (with, with_binds),
179 sql_union: (sql_union, sql_union_binds),
180 limit,
181 offset,
182 group_by,
183 group_by_raw: (group_by_raw, group_by_raw_binds),
184 having: (having, having_binds),
185 order_by,
186 order_by_raw: (order_by_raw, order_by_raw_binds),
187 }
188}
189
190pub fn merge_to_sql(to_sql: ToSql) -> (String, Vec<Value>) {
191 let mut select_sql = String::new();
192 let mut select_binds: Vec<serde_json::Value> = vec![];
193
194 if !to_sql.sql_with.0.is_empty() {
209 select_sql.push_str(to_sql.sql_with.0.as_str());
210 select_binds.extend(to_sql.sql_with.1);
211 }
212 if !to_sql.method.0.is_empty() {
213 select_sql.push_str(to_sql.method.0.as_str());
214 select_binds.extend(to_sql.method.1);
215 }
216 if !to_sql.join.0.is_empty() {
217 select_sql.push(' ');
218 select_sql.push_str(to_sql.join.0.as_str());
219 select_binds.extend(to_sql.join.1);
220 }
221 if !to_sql.statement.0.is_empty() {
222 select_sql.push(' ');
223 select_sql.push_str(to_sql.statement.0.as_str());
224 select_binds.extend(to_sql.statement.1);
225 }
226 if !to_sql.group_by.is_empty() {
227 select_sql.push_str(" GROUP BY ");
228 select_sql.push_str(to_sql.group_by.join(", ").as_str());
229 }
230 if !to_sql.group_by_raw.0.is_empty() {
231 select_sql.push_str(" GROUP BY ");
232 select_sql.push_str(to_sql.group_by_raw.0.as_str());
233 select_binds.extend(to_sql.group_by_raw.1);
234 }
235 if !to_sql.having.0.is_empty() {
236 select_sql.push_str(" HAVING ");
237 select_sql.push_str(to_sql.having.0.as_str());
238 select_binds.extend(to_sql.having.1);
239 }
240 if !to_sql.order_by.is_empty() {
241 select_sql.push_str(" ORDER BY ");
242 select_sql.push_str(to_sql.order_by.join(", ").as_str());
243 }
244 if !to_sql.order_by_raw.0.is_empty() {
245 select_sql.push_str(" ORDER BY ");
246 select_sql.push_str(to_sql.order_by_raw.0.as_str());
247 select_binds.extend(to_sql.order_by_raw.1);
248 }
249 if let Some(limit) = to_sql.limit {
250 select_sql.push(' ');
251 select_sql.push_str("LIMIT ?");
252 select_binds.push(serde_json::Value::Number(serde_json::Number::from(limit)));
253 }
254 if let Some(offset) = to_sql.offset {
255 select_sql.push(' ');
256 select_sql.push_str("OFFSET ?");
257 select_binds.push(serde_json::Value::Number(serde_json::Number::from(offset)));
258 }
259 if !to_sql.sql_union.0.is_empty() {
260 select_sql.push(' ');
261 select_sql.push_str(to_sql.sql_union.0.as_str());
262 select_binds.extend(to_sql.sql_union.1);
263 }
264 if !to_sql.raw.0.is_empty() {
265 select_sql.push(' ');
266 select_sql.push_str(to_sql.raw.0.as_str());
267 select_binds.extend(to_sql.raw.1);
268 }
269
270 (select_sql, select_binds)
271}