1use crate::query::QueryBuilder;
4use crate::types::{Client, Common, Method, Select};
5use serde_json::Value;
6
7#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
13pub struct ChainBuilder {
14 client: Client,
16 pub(crate) db: Option<String>,
18 pub(crate) table: Option<String>,
20 pub(crate) table_raw: Option<(String, Option<Vec<Value>>)>,
22 pub(crate) as_name: Option<String>,
24 pub(crate) select: Vec<Select>,
26 pub(crate) query: QueryBuilder,
28 pub(crate) method: Method,
30 pub(crate) insert_update: Value,
32 pub(crate) sql_str: String,
34 pub(crate) is_distinct: bool,
36}
37
38impl ChainBuilder {
39 pub fn new(client: Client) -> ChainBuilder {
41 let query = QueryBuilder::new(client.clone());
42 ChainBuilder {
43 client,
44 table: None,
45 table_raw: None,
46 select: Vec::new(),
47 as_name: None,
48 db: None,
49 query,
50 method: Method::Select,
51 insert_update: Value::Null,
52 sql_str: String::new(),
53 is_distinct: false,
54 }
55 }
56
57 #[cfg(feature = "mysql")]
59 pub fn new_mysql() -> ChainBuilder {
60 ChainBuilder::new(Client::Mysql)
61 }
62
63 #[cfg(feature = "sqlite")]
64 pub fn new_sqlite() -> ChainBuilder {
65 ChainBuilder::new(Client::Sqlite)
66 }
67
68 pub fn db(&mut self, db: &str) -> &mut ChainBuilder {
70 self.db = Some(db.to_string());
71 self
72 }
73
74 pub fn table(&mut self, table: &str) -> &mut ChainBuilder {
76 self.table = Some(table.to_string());
77 self
78 }
79
80 pub fn table_raw(&mut self, table: &str, val: Option<Vec<Value>>) -> &mut ChainBuilder {
82 self.table_raw = Some((table.to_string(), val));
83 self
84 }
85
86 pub fn distinct(&mut self) -> &mut ChainBuilder {
88 self.is_distinct = true;
89 self
90 }
91
92 pub fn select(&mut self, select: Select) -> &mut ChainBuilder {
94 self.method = Method::Select;
95 self.select.push(select);
96 self
97 }
98
99 pub fn select_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) -> &mut ChainBuilder {
101 self.method = Method::Select;
102 self.select.push(Select::Raw(sql.to_string(), binds));
103 self
104 }
105
106 pub fn select_distinct(&mut self, columns: Vec<String>) -> &mut ChainBuilder {
108 self.method = Method::Select;
109 self.is_distinct = true;
110 self.select.push(Select::Columns(columns));
111 self
112 }
113
114 pub fn select_count(&mut self, column: &str) -> &mut ChainBuilder {
116 self.method = Method::Select;
117 let column = crate::dialect::escape_identifier(column, &self.client);
118 self.select.push(Select::Raw(format!("COUNT({})", column), None));
119 self
120 }
121
122 pub fn select_sum(&mut self, column: &str) -> &mut ChainBuilder {
124 self.method = Method::Select;
125 let column = crate::dialect::escape_identifier(column, &self.client);
126 self.select.push(Select::Raw(format!("SUM({})", column), None));
127 self
128 }
129
130 pub fn select_avg(&mut self, column: &str) -> &mut ChainBuilder {
132 self.method = Method::Select;
133 let column = crate::dialect::escape_identifier(column, &self.client);
134 self.select.push(Select::Raw(format!("AVG({})", column), None));
135 self
136 }
137
138 pub fn select_max(&mut self, column: &str) -> &mut ChainBuilder {
140 self.method = Method::Select;
141 let column = crate::dialect::escape_identifier(column, &self.client);
142 self.select.push(Select::Raw(format!("MAX({})", column), None));
143 self
144 }
145
146 pub fn select_min(&mut self, column: &str) -> &mut ChainBuilder {
148 self.method = Method::Select;
149 let column = crate::dialect::escape_identifier(column, &self.client);
150 self.select.push(Select::Raw(format!("MIN({})", column), None));
151 self
152 }
153
154 pub fn select_alias(&mut self, column: &str, alias: &str) -> &mut ChainBuilder {
156 self.method = Method::Select;
157 let column = crate::dialect::escape_identifier(column, &self.client);
158 let alias = crate::dialect::escape_identifier(alias, &self.client);
159 self.select
160 .push(Select::Raw(format!("{} AS {}", column, alias), None));
161 self
162 }
163
164 pub fn insert(&mut self, data: Value) -> &mut ChainBuilder {
166 self.method = Method::Insert;
167 self.insert_update = data;
168 self
169 }
170
171 pub fn insert_many(&mut self, data: Vec<Value>) -> &mut ChainBuilder {
173 self.method = Method::InsertMany;
174 self.insert_update = Value::Array(data);
175 self
176 }
177
178 pub fn update(&mut self, data: Value) -> &mut ChainBuilder {
180 self.method = Method::Update;
181 self.insert_update = data;
182 self
183 }
184
185 pub fn insert_ignore(&mut self, data: Value) -> &mut ChainBuilder {
187 self.method = Method::Insert;
188 self.insert_update = data;
189 self
191 }
192
193 pub fn insert_or_update(&mut self, data: Value, _update_data: Value) -> &mut ChainBuilder {
195 self.method = Method::Insert;
196 self.insert_update = data;
197 self
199 }
200
201 pub fn update_raw(&mut self, _sql: &str, _binds: Option<Vec<Value>>) -> &mut ChainBuilder {
203 self.method = Method::Update;
204 self
206 }
207
208 pub fn increment(&mut self, column: &str, amount: i64) -> &mut ChainBuilder {
210 self.method = Method::Update;
211 let update_data = serde_json::json!({
212 column: format!("{} + {}", column, amount)
213 });
214 self.insert_update = update_data;
215 self
216 }
217
218 pub fn decrement(&mut self, column: &str, amount: i64) -> &mut ChainBuilder {
220 self.method = Method::Update;
221 let update_data = serde_json::json!({
222 column: format!("{} - {}", column, amount)
223 });
224 self.insert_update = update_data;
225 self
226 }
227
228 pub fn delete(&mut self) -> &mut ChainBuilder {
230 self.method = Method::Delete;
231 self
232 }
233
234 pub fn as_name(&mut self, name: &str) -> &mut ChainBuilder {
236 self.as_name = Some(name.to_string());
237 self
238 }
239
240 pub fn with(&mut self, alias: &str, chain_builder: ChainBuilder) -> &mut ChainBuilder {
242 self.query
243 .query_common
244 .push(Common::With(alias.to_string(), false, chain_builder));
245 self
246 }
247
248 pub fn with_recursive(
250 &mut self,
251 alias: &str,
252 chain_builder: ChainBuilder,
253 ) -> &mut ChainBuilder {
254 self.query
255 .query_common
256 .push(Common::With(alias.to_string(), true, chain_builder));
257 self
258 }
259
260 pub fn union(&mut self, chain_builder: ChainBuilder) -> &mut ChainBuilder {
262 self.query
263 .query_common
264 .push(Common::Union(false, chain_builder));
265 self
266 }
267
268 pub fn union_all(&mut self, chain_builder: ChainBuilder) -> &mut ChainBuilder {
270 self.query
271 .query_common
272 .push(Common::Union(true, chain_builder));
273 self
274 }
275
276 pub fn query(&mut self, query: impl FnOnce(&mut QueryBuilder)) {
278 query(&mut self.query);
279 }
280
281 pub fn add_raw(&mut self, sql: &str, val: Option<Vec<Value>>) {
283 self.query.raw.push((sql.to_string(), val));
284 }
285
286 pub fn to_sql(&mut self) -> (String, Vec<Value>) {
288 match self.client {
289 #[cfg(feature = "mysql")]
290 Client::Mysql => {
291 let rs = crate::mysql::merge_to_sql(crate::mysql::to_sql(self));
292 self.sql_str = rs.0.clone();
293 (self.sql_str.clone(), rs.1)
294 }
295 #[cfg(feature = "sqlite")]
296 Client::Sqlite => {
297 let rs = crate::sqlite::merge_to_sql(crate::sqlite::to_sql(self));
298 self.sql_str = rs.0.clone();
299 (self.sql_str.clone(), rs.1)
300 }
301 #[cfg(feature = "postgres")]
302 Client::Postgres => {
303 panic!("PostgreSQL support not yet implemented");
304 }
305 _ => {
306 panic!("Unsupported database client");
307 }
308 }
309 }
310}