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 ChainBuilder {
42 client,
43 table: None,
44 table_raw: None,
45 select: Vec::new(),
46 as_name: None,
47 db: None,
48 query: QueryBuilder::default(),
49 method: Method::Select,
50 insert_update: Value::Null,
51 sql_str: String::new(),
52 is_distinct: false,
53 }
54 }
55
56 #[cfg(feature = "mysql")]
58 pub fn new_mysql() -> ChainBuilder {
59 ChainBuilder::new(Client::Mysql)
60 }
61
62 #[cfg(feature = "sqlite")]
63 pub fn new_sqlite() -> ChainBuilder {
64 ChainBuilder::new(Client::Sqlite)
65 }
66
67 pub fn db(&mut self, db: &str) -> &mut ChainBuilder {
69 self.db = Some(db.to_string());
70 self
71 }
72
73 pub fn table(&mut self, table: &str) -> &mut ChainBuilder {
75 self.table = Some(table.to_string());
76 self
77 }
78
79 pub fn table_raw(&mut self, table: &str, val: Option<Vec<Value>>) -> &mut ChainBuilder {
81 self.table_raw = Some((table.to_string(), val));
82 self
83 }
84
85 pub fn distinct(&mut self) -> &mut ChainBuilder {
87 self.is_distinct = true;
88 self
89 }
90
91 pub fn select(&mut self, select: Select) -> &mut ChainBuilder {
93 self.method = Method::Select;
94 self.select.push(select);
95 self
96 }
97
98 pub fn select_raw(&mut self, sql: &str, binds: Option<Vec<Value>>) -> &mut ChainBuilder {
100 self.method = Method::Select;
101 self.select.push(Select::Raw(sql.to_string(), binds));
102 self
103 }
104
105 pub fn select_distinct(&mut self, columns: Vec<String>) -> &mut ChainBuilder {
107 self.method = Method::Select;
108 self.is_distinct = true;
109 self.select.push(Select::Columns(columns));
110 self
111 }
112
113 pub fn select_count(&mut self, column: &str) -> &mut ChainBuilder {
115 self.method = Method::Select;
116 self.select
117 .push(Select::Raw(format!("COUNT({})", column), None));
118 self
119 }
120
121 pub fn select_sum(&mut self, column: &str) -> &mut ChainBuilder {
123 self.method = Method::Select;
124 self.select
125 .push(Select::Raw(format!("SUM({})", column), None));
126 self
127 }
128
129 pub fn select_avg(&mut self, column: &str) -> &mut ChainBuilder {
131 self.method = Method::Select;
132 self.select
133 .push(Select::Raw(format!("AVG({})", column), None));
134 self
135 }
136
137 pub fn select_max(&mut self, column: &str) -> &mut ChainBuilder {
139 self.method = Method::Select;
140 self.select
141 .push(Select::Raw(format!("MAX({})", column), None));
142 self
143 }
144
145 pub fn select_min(&mut self, column: &str) -> &mut ChainBuilder {
147 self.method = Method::Select;
148 self.select
149 .push(Select::Raw(format!("MIN({})", column), None));
150 self
151 }
152
153 pub fn select_alias(&mut self, column: &str, alias: &str) -> &mut ChainBuilder {
155 self.method = Method::Select;
156 self.select
157 .push(Select::Raw(format!("{} AS {}", column, alias), None));
158 self
159 }
160
161 pub fn insert(&mut self, data: Value) -> &mut ChainBuilder {
163 self.method = Method::Insert;
164 self.insert_update = data;
165 self
166 }
167
168 pub fn insert_many(&mut self, data: Vec<Value>) -> &mut ChainBuilder {
170 self.method = Method::InsertMany;
171 self.insert_update = Value::Array(data);
172 self
173 }
174
175 pub fn update(&mut self, data: Value) -> &mut ChainBuilder {
177 self.method = Method::Update;
178 self.insert_update = data;
179 self
180 }
181
182 pub fn insert_ignore(&mut self, data: Value) -> &mut ChainBuilder {
184 self.method = Method::Insert;
185 self.insert_update = data;
186 self
188 }
189
190 pub fn insert_or_update(&mut self, data: Value, _update_data: Value) -> &mut ChainBuilder {
192 self.method = Method::Insert;
193 self.insert_update = data;
194 self
196 }
197
198 pub fn update_raw(&mut self, _sql: &str, _binds: Option<Vec<Value>>) -> &mut ChainBuilder {
200 self.method = Method::Update;
201 self
203 }
204
205 pub fn increment(&mut self, column: &str, amount: i64) -> &mut ChainBuilder {
207 self.method = Method::Update;
208 let update_data = serde_json::json!({
209 column: format!("{} + {}", column, amount)
210 });
211 self.insert_update = update_data;
212 self
213 }
214
215 pub fn decrement(&mut self, column: &str, amount: i64) -> &mut ChainBuilder {
217 self.method = Method::Update;
218 let update_data = serde_json::json!({
219 column: format!("{} - {}", column, amount)
220 });
221 self.insert_update = update_data;
222 self
223 }
224
225 pub fn delete(&mut self) -> &mut ChainBuilder {
227 self.method = Method::Delete;
228 self
229 }
230
231 pub fn as_name(&mut self, name: &str) -> &mut ChainBuilder {
233 self.as_name = Some(name.to_string());
234 self
235 }
236
237 pub fn with(&mut self, alias: &str, chain_builder: ChainBuilder) -> &mut ChainBuilder {
239 self.query
240 .query_common
241 .push(Common::With(alias.to_string(), false, chain_builder));
242 self
243 }
244
245 pub fn with_recursive(
247 &mut self,
248 alias: &str,
249 chain_builder: ChainBuilder,
250 ) -> &mut ChainBuilder {
251 self.query
252 .query_common
253 .push(Common::With(alias.to_string(), true, chain_builder));
254 self
255 }
256
257 pub fn union(&mut self, chain_builder: ChainBuilder) -> &mut ChainBuilder {
259 self.query
260 .query_common
261 .push(Common::Union(false, chain_builder));
262 self
263 }
264
265 pub fn union_all(&mut self, chain_builder: ChainBuilder) -> &mut ChainBuilder {
267 self.query
268 .query_common
269 .push(Common::Union(true, chain_builder));
270 self
271 }
272
273 pub fn query(&mut self, query: impl FnOnce(&mut QueryBuilder)) {
275 query(&mut self.query);
276 }
277
278 pub fn add_raw(&mut self, sql: &str, val: Option<Vec<Value>>) {
280 self.query.raw.push((sql.to_string(), val));
281 }
282
283 pub fn to_sql(&mut self) -> (String, Vec<Value>) {
285 match self.client {
286 #[cfg(feature = "mysql")]
287 Client::Mysql => {
288 let rs = crate::mysql::merge_to_sql(crate::mysql::to_sql(self));
289 self.sql_str = rs.0.clone();
290 (self.sql_str.clone(), rs.1)
291 }
292 #[cfg(feature = "sqlite")]
293 Client::Sqlite => {
294 let rs = crate::sqlite::merge_to_sql(crate::sqlite::to_sql(self));
295 self.sql_str = rs.0.clone();
296 (self.sql_str.clone(), rs.1)
297 }
298 #[cfg(feature = "postgres")]
299 Client::Postgres => {
300 panic!("PostgreSQL support not yet implemented");
301 }
302 _ => {
303 panic!("Unsupported database client");
304 }
305 }
306 }
307}