Skip to main content

wae_database/orm/
condition.rs

1//! 查询条件模块
2//!
3//! 提供查询条件构建和排序方式定义
4
5use wae_types::Value;
6
7#[cfg(feature = "turso")]
8use crate::types::from_wae_value;
9#[cfg(feature = "turso")]
10use turso::Value as TursoValue;
11
12#[cfg(feature = "mysql")]
13use crate::types::from_wae_to_mysql;
14#[cfg(feature = "mysql")]
15use mysql_async::Value as MySqlValue;
16
17/// 查询条件
18#[derive(Debug, Clone)]
19pub enum Condition {
20    /// 相等条件
21    Eq {
22        /// 列名
23        column: String,
24        /// 值
25        value: Value,
26    },
27    /// 不相等条件
28    Ne {
29        /// 列名
30        column: String,
31        /// 值
32        value: Value,
33    },
34    /// 大于条件
35    Gt {
36        /// 列名
37        column: String,
38        /// 值
39        value: Value,
40    },
41    /// 大于等于条件
42    Gte {
43        /// 列名
44        column: String,
45        /// 值
46        value: Value,
47    },
48    /// 小于条件
49    Lt {
50        /// 列名
51        column: String,
52        /// 值
53        value: Value,
54    },
55    /// 小于等于条件
56    Lte {
57        /// 列名
58        column: String,
59        /// 值
60        value: Value,
61    },
62    /// LIKE 条件
63    Like {
64        /// 列名
65        column: String,
66        /// 模式
67        pattern: String,
68    },
69    /// IN 条件
70    In {
71        /// 列名
72        column: String,
73        /// 值列表
74        values: Vec<Value>,
75    },
76    /// IS NULL 条件
77    IsNull {
78        /// 列名
79        column: String,
80    },
81    /// IS NOT NULL 条件
82    IsNotNull {
83        /// 列名
84        column: String,
85    },
86    /// AND 组合
87    And(Vec<Condition>),
88    /// OR 组合
89    Or(Vec<Condition>),
90    /// NOT 条件
91    Not(Box<Condition>),
92    /// 原始 SQL 条件
93    Raw {
94        /// SQL 片段
95        sql: String,
96        /// 参数
97        params: Vec<Value>,
98    },
99}
100
101impl Condition {
102    /// 创建相等条件
103    pub fn eq<C: Into<String>, V: Into<Value>>(column: C, value: V) -> Self {
104        Condition::Eq { column: column.into(), value: value.into() }
105    }
106
107    /// 创建不相等条件
108    pub fn ne<C: Into<String>, V: Into<Value>>(column: C, value: V) -> Self {
109        Condition::Ne { column: column.into(), value: value.into() }
110    }
111
112    /// 创建大于条件
113    pub fn gt<C: Into<String>, V: Into<Value>>(column: C, value: V) -> Self {
114        Condition::Gt { column: column.into(), value: value.into() }
115    }
116
117    /// 创建大于等于条件
118    pub fn gte<C: Into<String>, V: Into<Value>>(column: C, value: V) -> Self {
119        Condition::Gte { column: column.into(), value: value.into() }
120    }
121
122    /// 创建小于条件
123    pub fn lt<C: Into<String>, V: Into<Value>>(column: C, value: V) -> Self {
124        Condition::Lt { column: column.into(), value: value.into() }
125    }
126
127    /// 创建小于等于条件
128    pub fn lte<C: Into<String>, V: Into<Value>>(column: C, value: V) -> Self {
129        Condition::Lte { column: column.into(), value: value.into() }
130    }
131
132    /// 创建 LIKE 条件
133    pub fn like<C: Into<String>, P: Into<String>>(column: C, pattern: P) -> Self {
134        Condition::Like { column: column.into(), pattern: pattern.into() }
135    }
136
137    /// 创建 IN 条件
138    pub fn in_<C: Into<String>, V: Into<Value>>(column: C, values: Vec<V>) -> Self {
139        Condition::In { column: column.into(), values: values.into_iter().map(|v| v.into()).collect() }
140    }
141
142    /// 创建 IS NULL 条件
143    pub fn is_null<C: Into<String>>(column: C) -> Self {
144        Condition::IsNull { column: column.into() }
145    }
146
147    /// 创建 IS NOT NULL 条件
148    pub fn is_not_null<C: Into<String>>(column: C) -> Self {
149        Condition::IsNotNull { column: column.into() }
150    }
151
152    /// 创建 AND 组合
153    pub fn and(conditions: Vec<Condition>) -> Self {
154        Condition::And(conditions)
155    }
156
157    /// 创建 OR 组合
158    pub fn or(conditions: Vec<Condition>) -> Self {
159        Condition::Or(conditions)
160    }
161
162    /// 创建 NOT 条件
163    pub fn negate(condition: Condition) -> Self {
164        Condition::Not(Box::new(condition))
165    }
166
167    /// 创建原始 SQL 条件
168    pub fn raw<S: Into<String>>(sql: S, params: Vec<Value>) -> Self {
169        Condition::Raw { sql: sql.into(), params }
170    }
171
172    #[cfg(feature = "turso")]
173    /// 构建 SQL 和参数 (内部使用 turso::Value)
174    pub(crate) fn build_turso(&self) -> (String, Vec<TursoValue>) {
175        match self {
176            Condition::Eq { column, value } => (format!("{} = ?", column), vec![from_wae_value(value.clone())]),
177            Condition::Ne { column, value } => (format!("{} != ?", column), vec![from_wae_value(value.clone())]),
178            Condition::Gt { column, value } => (format!("{} > ?", column), vec![from_wae_value(value.clone())]),
179            Condition::Gte { column, value } => (format!("{} >= ?", column), vec![from_wae_value(value.clone())]),
180            Condition::Lt { column, value } => (format!("{} < ?", column), vec![from_wae_value(value.clone())]),
181            Condition::Lte { column, value } => (format!("{} <= ?", column), vec![from_wae_value(value.clone())]),
182            Condition::Like { column, pattern } => (format!("{} LIKE ?", column), vec![TursoValue::Text(pattern.clone())]),
183            Condition::In { column, values } => {
184                let placeholders: Vec<&str> = values.iter().map(|_| "?").collect();
185                let turso_values: Vec<TursoValue> = values.iter().map(|v| from_wae_value(v.clone())).collect();
186                (format!("{} IN ({})", column, placeholders.join(", ")), turso_values)
187            }
188            Condition::IsNull { column } => (format!("{} IS NULL", column), vec![]),
189            Condition::IsNotNull { column } => (format!("{} IS NOT NULL", column), vec![]),
190            Condition::And(conditions) => {
191                let mut sql_parts = Vec::new();
192                let mut all_params = Vec::new();
193                for cond in conditions {
194                    let (sql, params) = cond.build_turso();
195                    sql_parts.push(format!("({})", sql));
196                    all_params.extend(params);
197                }
198                (sql_parts.join(" AND "), all_params)
199            }
200            Condition::Or(conditions) => {
201                let mut sql_parts = Vec::new();
202                let mut all_params = Vec::new();
203                for cond in conditions {
204                    let (sql, params) = cond.build_turso();
205                    sql_parts.push(format!("({})", sql));
206                    all_params.extend(params);
207                }
208                (sql_parts.join(" OR "), all_params)
209            }
210            Condition::Not(cond) => {
211                let (sql, params) = cond.build_turso();
212                (format!("NOT ({})", sql), params)
213            }
214            Condition::Raw { sql, params } => {
215                let turso_params: Vec<TursoValue> = params.iter().map(|v| from_wae_value(v.clone())).collect();
216                (sql.clone(), turso_params)
217            }
218        }
219    }
220
221    #[cfg(feature = "mysql")]
222    /// 构建 SQL 和参数 (内部使用 MySQL Value)
223    pub(crate) fn build_mysql(&self) -> (String, Vec<MySqlValue>) {
224        match self {
225            Condition::Eq { column, value } => (format!("{} = ?", column), vec![from_wae_to_mysql(value.clone())]),
226            Condition::Ne { column, value } => (format!("{} != ?", column), vec![from_wae_to_mysql(value.clone())]),
227            Condition::Gt { column, value } => (format!("{} > ?", column), vec![from_wae_to_mysql(value.clone())]),
228            Condition::Gte { column, value } => (format!("{} >= ?", column), vec![from_wae_to_mysql(value.clone())]),
229            Condition::Lt { column, value } => (format!("{} < ?", column), vec![from_wae_to_mysql(value.clone())]),
230            Condition::Lte { column, value } => (format!("{} <= ?", column), vec![from_wae_to_mysql(value.clone())]),
231            Condition::Like { column, pattern } => {
232                (format!("{} LIKE ?", column), vec![MySqlValue::Bytes(pattern.clone().into_bytes())])
233            }
234            Condition::In { column, values } => {
235                let placeholders: Vec<&str> = values.iter().map(|_| "?").collect();
236                let mysql_values: Vec<MySqlValue> = values.iter().map(|v| from_wae_to_mysql(v.clone())).collect();
237                (format!("{} IN ({})", column, placeholders.join(", ")), mysql_values)
238            }
239            Condition::IsNull { column } => (format!("{} IS NULL", column), vec![]),
240            Condition::IsNotNull { column } => (format!("{} IS NOT NULL", column), vec![]),
241            Condition::And(conditions) => {
242                let mut sql_parts = Vec::new();
243                let mut all_params = Vec::new();
244                for cond in conditions {
245                    let (sql, params) = cond.build_mysql();
246                    sql_parts.push(format!("({})", sql));
247                    all_params.extend(params);
248                }
249                (sql_parts.join(" AND "), all_params)
250            }
251            Condition::Or(conditions) => {
252                let mut sql_parts = Vec::new();
253                let mut all_params = Vec::new();
254                for cond in conditions {
255                    let (sql, params) = cond.build_mysql();
256                    sql_parts.push(format!("({})", sql));
257                    all_params.extend(params);
258                }
259                (sql_parts.join(" OR "), all_params)
260            }
261            Condition::Not(cond) => {
262                let (sql, params) = cond.build_mysql();
263                (format!("NOT ({})", sql), params)
264            }
265            Condition::Raw { sql, params } => {
266                let mysql_params: Vec<MySqlValue> = params.iter().map(|v| from_wae_to_mysql(v.clone())).collect();
267                (sql.clone(), mysql_params)
268            }
269        }
270    }
271}
272
273/// 排序方式
274#[derive(Debug, Clone, Copy)]
275pub enum Order {
276    /// 升序
277    Asc,
278    /// 降序
279    Desc,
280}