Skip to main content

wae_database/orm/
builder.rs

1//! 查询构建器模块
2//!
3//! 提供 SELECT、INSERT、UPDATE、DELETE 查询构建器
4
5use super::{
6    condition::{Condition, Order},
7    entity::{Entity, ToRow},
8};
9use std::marker::PhantomData;
10use wae_types::Value;
11
12#[cfg(feature = "turso")]
13use crate::types::from_wae_value;
14#[cfg(feature = "turso")]
15use turso::Value as TursoValue;
16
17#[cfg(feature = "mysql")]
18use crate::types::from_wae_to_mysql;
19#[cfg(feature = "mysql")]
20use mysql_async::Value as MySqlValue;
21
22/// SELECT 查询构建器
23pub struct SelectBuilder<E: Entity> {
24    columns: Vec<String>,
25    conditions: Vec<Condition>,
26    order_by: Vec<(String, Order)>,
27    limit: Option<u64>,
28    offset: Option<u64>,
29    _marker: PhantomData<E>,
30}
31
32impl<E: Entity> SelectBuilder<E> {
33    pub(crate) fn new() -> Self {
34        Self {
35            columns: Vec::new(),
36            conditions: Vec::new(),
37            order_by: Vec::new(),
38            limit: None,
39            offset: None,
40            _marker: PhantomData,
41        }
42    }
43
44    /// 选择指定列
45    pub fn columns(mut self, columns: &[&str]) -> Self {
46        self.columns = columns.iter().map(|s| s.to_string()).collect();
47        self
48    }
49
50    /// 添加 WHERE 条件
51    pub fn where_(mut self, condition: Condition) -> Self {
52        self.conditions.push(condition);
53        self
54    }
55
56    /// 添加多个 WHERE 条件 (AND 连接)
57    pub fn where_all(mut self, conditions: Vec<Condition>) -> Self {
58        self.conditions.extend(conditions);
59        self
60    }
61
62    /// 添加排序
63    pub fn order_by<C: Into<String>>(mut self, column: C, order: Order) -> Self {
64        self.order_by.push((column.into(), order));
65        self
66    }
67
68    /// 设置 LIMIT
69    pub fn limit(mut self, limit: u64) -> Self {
70        self.limit = Some(limit);
71        self
72    }
73
74    /// 设置 OFFSET
75    pub fn offset(mut self, offset: u64) -> Self {
76        self.offset = Some(offset);
77        self
78    }
79
80    #[cfg(feature = "turso")]
81    /// 构建 SQL 和参数 (内部使用)
82    pub(crate) fn build_turso(&self) -> (String, Vec<TursoValue>) {
83        let columns = if self.columns.is_empty() { "*".to_string() } else { self.columns.join(", ") };
84
85        let mut sql = format!("SELECT {} FROM {}", columns, E::table_name());
86        let mut params = Vec::new();
87
88        if !self.conditions.is_empty() {
89            let where_conditions = self.conditions.to_vec();
90            if where_conditions.len() == 1 {
91                let (cond_sql, cond_params) = where_conditions[0].build_turso();
92                sql.push_str(&format!(" WHERE {}", cond_sql));
93                params.extend(cond_params);
94            }
95            else {
96                let (cond_sql, cond_params) = Condition::and(where_conditions).build_turso();
97                sql.push_str(&format!(" WHERE {}", cond_sql));
98                params.extend(cond_params);
99            }
100        }
101
102        if !self.order_by.is_empty() {
103            let order_parts: Vec<String> = self
104                .order_by
105                .iter()
106                .map(|(col, order)| {
107                    format!(
108                        "{} {}",
109                        col,
110                        match order {
111                            Order::Asc => "ASC",
112                            Order::Desc => "DESC",
113                        }
114                    )
115                })
116                .collect();
117            sql.push_str(&format!(" ORDER BY {}", order_parts.join(", ")));
118        }
119
120        if let Some(limit) = self.limit {
121            sql.push_str(&format!(" LIMIT {}", limit));
122        }
123
124        if let Some(offset) = self.offset {
125            sql.push_str(&format!(" OFFSET {}", offset));
126        }
127
128        (sql, params)
129    }
130
131    #[cfg(feature = "mysql")]
132    #[allow(dead_code)]
133    /// 构建 SQL 和参数 (内部使用 MySQL)
134    pub(crate) fn build_mysql(&self) -> (String, Vec<MySqlValue>) {
135        let columns = if self.columns.is_empty() { "*".to_string() } else { self.columns.join(", ") };
136
137        let mut sql = format!("SELECT {} FROM {}", columns, E::table_name());
138        let mut params = Vec::new();
139
140        if !self.conditions.is_empty() {
141            let where_conditions = self.conditions.to_vec();
142            if where_conditions.len() == 1 {
143                let (cond_sql, cond_params) = where_conditions[0].build_mysql();
144                sql.push_str(&format!(" WHERE {}", cond_sql));
145                params.extend(cond_params);
146            }
147            else {
148                let (cond_sql, cond_params) = Condition::and(where_conditions).build_mysql();
149                sql.push_str(&format!(" WHERE {}", cond_sql));
150                params.extend(cond_params);
151            }
152        }
153
154        if !self.order_by.is_empty() {
155            let order_parts: Vec<String> = self
156                .order_by
157                .iter()
158                .map(|(col, order)| {
159                    format!(
160                        "{} {}",
161                        col,
162                        match order {
163                            Order::Asc => "ASC",
164                            Order::Desc => "DESC",
165                        }
166                    )
167                })
168                .collect();
169            sql.push_str(&format!(" ORDER BY {}", order_parts.join(", ")));
170        }
171
172        if let Some(limit) = self.limit {
173            sql.push_str(&format!(" LIMIT {}", limit));
174        }
175
176        if let Some(offset) = self.offset {
177            sql.push_str(&format!(" OFFSET {}", offset));
178        }
179
180        (sql, params)
181    }
182}
183
184/// INSERT 查询构建器
185pub struct InsertBuilder<E: Entity> {
186    data: Vec<(&'static str, Value)>,
187    _marker: PhantomData<E>,
188}
189
190impl<E: Entity> InsertBuilder<E> {
191    pub(crate) fn new() -> Self {
192        Self { data: Vec::new(), _marker: PhantomData }
193    }
194
195    /// 从实体创建
196    pub fn from_entity<T: ToRow>(entity: &T) -> Self {
197        Self { data: entity.to_row(), _marker: PhantomData }
198    }
199
200    /// 添加列值
201    pub fn value(mut self, column: &'static str, value: Value) -> Self {
202        self.data.push((column, value));
203        self
204    }
205
206    /// 批量添加列值
207    pub fn values(mut self, data: Vec<(&'static str, Value)>) -> Self {
208        self.data.extend(data);
209        self
210    }
211
212    #[cfg(feature = "turso")]
213    /// 构建 SQL 和参数 (内部使用)
214    pub(crate) fn build_turso(&self) -> (String, Vec<TursoValue>) {
215        let columns: Vec<&str> = self.data.iter().map(|(col, _)| *col).collect();
216        let placeholders: Vec<&str> = self.data.iter().map(|_| "?").collect();
217        let params: Vec<TursoValue> = self.data.iter().map(|(_, val)| from_wae_value(val.clone())).collect();
218
219        let sql = format!("INSERT INTO {} ({}) VALUES ({})", E::table_name(), columns.join(", "), placeholders.join(", "));
220
221        (sql, params)
222    }
223
224    #[cfg(feature = "mysql")]
225    /// 构建 SQL 和参数 (内部使用 MySQL)
226    pub(crate) fn build_mysql(&self) -> (String, Vec<MySqlValue>) {
227        let columns: Vec<&str> = self.data.iter().map(|(col, _)| *col).collect();
228        let placeholders: Vec<&str> = self.data.iter().map(|_| "?").collect();
229        let params: Vec<MySqlValue> = self.data.iter().map(|(_, val)| from_wae_to_mysql(val.clone())).collect();
230
231        let sql = format!("INSERT INTO {} ({}) VALUES ({})", E::table_name(), columns.join(", "), placeholders.join(", "));
232
233        (sql, params)
234    }
235}
236
237/// UPDATE 查询构建器
238pub struct UpdateBuilder<E: Entity> {
239    data: Vec<(&'static str, Value)>,
240    conditions: Vec<Condition>,
241    _marker: PhantomData<E>,
242}
243
244impl<E: Entity> UpdateBuilder<E> {
245    pub(crate) fn new() -> Self {
246        Self { data: Vec::new(), conditions: Vec::new(), _marker: PhantomData }
247    }
248
249    /// 设置列值
250    pub fn set(mut self, column: &'static str, value: Value) -> Self {
251        self.data.push((column, value));
252        self
253    }
254
255    /// 批量设置列值
256    pub fn set_all(mut self, data: Vec<(&'static str, Value)>) -> Self {
257        self.data.extend(data);
258        self
259    }
260
261    /// 从实体设置值 (排除主键)
262    pub fn from_entity<T: ToRow + Entity>(entity: &T) -> Self {
263        let id_col = T::id_column();
264        let data: Vec<(&'static str, Value)> = entity.to_row().into_iter().filter(|(col, _)| *col != id_col).collect();
265        Self { data, conditions: Vec::new(), _marker: PhantomData }
266    }
267
268    /// 添加 WHERE 条件
269    pub fn where_(mut self, condition: Condition) -> Self {
270        self.conditions.push(condition);
271        self
272    }
273
274    /// 按主键更新
275    pub fn where_id(mut self, id: E::Id) -> Self {
276        self.conditions.push(Condition::eq(E::id_column(), id));
277        self
278    }
279
280    #[cfg(feature = "turso")]
281    /// 构建 SQL 和参数 (内部使用)
282    pub(crate) fn build_turso(&self) -> (String, Vec<TursoValue>) {
283        let set_parts: Vec<String> = self.data.iter().map(|(col, _)| format!("{} = ?", col)).collect();
284        let mut params: Vec<TursoValue> = self.data.iter().map(|(_, val)| from_wae_value(val.clone())).collect();
285
286        let mut sql = format!("UPDATE {} SET {}", E::table_name(), set_parts.join(", "));
287
288        if !self.conditions.is_empty() {
289            let where_conditions = self.conditions.to_vec();
290            if where_conditions.len() == 1 {
291                let (cond_sql, cond_params) = where_conditions[0].build_turso();
292                sql.push_str(&format!(" WHERE {}", cond_sql));
293                params.extend(cond_params);
294            }
295            else {
296                let (cond_sql, cond_params) = Condition::and(where_conditions).build_turso();
297                sql.push_str(&format!(" WHERE {}", cond_sql));
298                params.extend(cond_params);
299            }
300        }
301
302        (sql, params)
303    }
304
305    #[cfg(feature = "mysql")]
306    /// 构建 SQL 和参数 (内部使用 MySQL)
307    pub(crate) fn build_mysql(&self) -> (String, Vec<MySqlValue>) {
308        let set_parts: Vec<String> = self.data.iter().map(|(col, _)| format!("{} = ?", col)).collect();
309        let mut params: Vec<MySqlValue> = self.data.iter().map(|(_, val)| from_wae_to_mysql(val.clone())).collect();
310
311        let mut sql = format!("UPDATE {} SET {}", E::table_name(), set_parts.join(", "));
312
313        if !self.conditions.is_empty() {
314            let where_conditions = self.conditions.to_vec();
315            if where_conditions.len() == 1 {
316                let (cond_sql, cond_params) = where_conditions[0].build_mysql();
317                sql.push_str(&format!(" WHERE {}", cond_sql));
318                params.extend(cond_params);
319            }
320            else {
321                let (cond_sql, cond_params) = Condition::and(where_conditions).build_mysql();
322                sql.push_str(&format!(" WHERE {}", cond_sql));
323                params.extend(cond_params);
324            }
325        }
326
327        (sql, params)
328    }
329}
330
331/// DELETE 查询构建器
332pub struct DeleteBuilder<E: Entity> {
333    conditions: Vec<Condition>,
334    _marker: PhantomData<E>,
335}
336
337impl<E: Entity> DeleteBuilder<E> {
338    pub(crate) fn new() -> Self {
339        Self { conditions: Vec::new(), _marker: PhantomData }
340    }
341
342    /// 添加 WHERE 条件
343    pub fn where_(mut self, condition: Condition) -> Self {
344        self.conditions.push(condition);
345        self
346    }
347
348    /// 按主键删除
349    pub fn where_id(mut self, id: E::Id) -> Self {
350        self.conditions.push(Condition::eq(E::id_column(), id));
351        self
352    }
353
354    #[cfg(feature = "turso")]
355    /// 构建 SQL 和参数 (内部使用)
356    pub(crate) fn build_turso(&self) -> (String, Vec<TursoValue>) {
357        let mut sql = format!("DELETE FROM {}", E::table_name());
358        let mut params = Vec::new();
359
360        if !self.conditions.is_empty() {
361            let where_conditions = self.conditions.to_vec();
362            if where_conditions.len() == 1 {
363                let (cond_sql, cond_params) = where_conditions[0].build_turso();
364                sql.push_str(&format!(" WHERE {}", cond_sql));
365                params.extend(cond_params);
366            }
367            else {
368                let (cond_sql, cond_params) = Condition::and(where_conditions).build_turso();
369                sql.push_str(&format!(" WHERE {}", cond_sql));
370                params.extend(cond_params);
371            }
372        }
373
374        (sql, params)
375    }
376
377    #[cfg(feature = "mysql")]
378    /// 构建 SQL 和参数 (内部使用 MySQL)
379    pub(crate) fn build_mysql(&self) -> (String, Vec<MySqlValue>) {
380        let mut sql = format!("DELETE FROM {}", E::table_name());
381        let mut params = Vec::new();
382
383        if !self.conditions.is_empty() {
384            let where_conditions = self.conditions.to_vec();
385            if where_conditions.len() == 1 {
386                let (cond_sql, cond_params) = where_conditions[0].build_mysql();
387                sql.push_str(&format!(" WHERE {}", cond_sql));
388                params.extend(cond_params);
389            }
390            else {
391                let (cond_sql, cond_params) = Condition::and(where_conditions).build_mysql();
392                sql.push_str(&format!(" WHERE {}", cond_sql));
393                params.extend(cond_params);
394            }
395        }
396
397        (sql, params)
398    }
399}
400
401/// 查询构建器入口
402pub struct QueryBuilder;
403
404impl QueryBuilder {
405    /// 创建 SELECT 构建器
406    pub fn select<E: Entity>() -> SelectBuilder<E> {
407        SelectBuilder::new()
408    }
409
410    /// 创建 INSERT 构建器
411    pub fn insert<E: Entity>() -> InsertBuilder<E> {
412        InsertBuilder::new()
413    }
414
415    /// 创建 UPDATE 构建器
416    pub fn update<E: Entity>() -> UpdateBuilder<E> {
417        UpdateBuilder::new()
418    }
419
420    /// 创建 DELETE 构建器
421    pub fn delete<E: Entity>() -> DeleteBuilder<E> {
422        DeleteBuilder::new()
423    }
424}