br_db/types/
mod.rs

1use json::{JsonValue, object};
2pub static DISABLE_FIELD: &[&str] = &["default", "select", "delete", "insert", "update", "order", "group", "user", "password", "desc", "index", "from", "host", "user", "read", "partition"];
3
4/// 验证表名格式,防止 SQL 注入
5pub fn validate_table_name(name: &str) -> Result<&str, String> {
6    let name = name.trim();
7    if name.is_empty() {
8        return Err("表名不能为空".to_string());
9    }
10    if name.contains('\'') || name.contains(';') || name.contains('"') || name.contains('`') {
11        return Err(format!("表名包含非法字符: {}", name));
12    }
13    Ok(name)
14}
15
16/// 添加表名前缀的公共函数
17pub fn add_table_prefix(prefix: &str, name: &str) -> String {
18    format!("{}{}", prefix, name)
19}
20
21#[cfg(feature = "db-sqlite")]
22pub mod sqlite;
23#[cfg(feature = "db-mysql")]
24pub mod mysql;
25#[cfg(feature = "db-mssql")]
26pub mod mssql;
27#[cfg(feature = "db-pgsql")]
28pub mod pgsql;
29
30pub trait DbMode {
31    /// 数据库是否存在
32    fn database_tables(&mut self) -> JsonValue;
33    /// 创建数据库
34    fn database_create(&mut self, name: &str) -> bool;
35    /// 更新数据库属性(PostgreSQL 支持)
36    fn database_update(&mut self, _name: &str, _options: JsonValue) -> bool {
37        false // 默认实现,MySQL 等不支持
38    }
39    /// 备份
40    fn backups(&mut self, _filename: &str) -> bool {
41        false
42    }
43}
44
45#[derive(Debug, Clone)]
46pub struct TableOptions {
47    table_name: String,
48    table_title: String,
49    table_key: String,
50    table_fields: JsonValue,
51    table_unique: Vec<String>,
52    table_index: Vec<Vec<String>>,
53    table_partition: bool,
54    table_partition_columns: JsonValue,
55}
56impl TableOptions {
57    pub fn set_table_name(&mut self, name: &str) {
58        self.table_name = name.to_string()
59    }
60    pub fn set_table_title(&mut self, name: &str) {
61        self.table_title = name.to_string()
62    }
63    pub fn set_table_key(&mut self, name: &str) {
64        self.table_key = name.to_string()
65    }
66    pub fn set_table_fields(&mut self, fields: JsonValue) {
67        self.table_fields = fields;
68    }
69    pub fn set_table_unique(&mut self, unique: Vec<&str>) {
70        self.table_unique = unique.iter().map(|s| s.to_string()).collect();
71    }
72    pub fn set_table_index(&mut self, index: Vec<Vec<&str>>) {
73        self.table_index = index.iter().map(|s| s.iter().map(|s| s.to_string()).collect()).collect();
74    }
75    pub fn set_table_partition(&mut self, index: bool) {
76        self.table_partition = index;
77    }
78    pub fn set_table_partition_columns(&mut self, index: JsonValue) {
79        self.table_partition_columns = index;
80    }
81}
82impl Default for TableOptions {
83    fn default() -> Self {
84        Self {
85            table_name: "".to_string(),
86            table_title: "".to_string(),
87            table_key: "".to_string(),
88            table_fields: JsonValue::Null,
89            table_unique: vec![],
90            table_index: vec![],
91            table_partition: false,
92            table_partition_columns: JsonValue::Null,
93        }
94    }
95}
96pub trait Mode: DbMode {
97    fn table_create(&mut self, options: TableOptions) -> JsonValue;
98    fn table_update(&mut self, options: TableOptions) -> JsonValue;
99    /// 获取表信息
100    fn table_info(&mut self, table: &str) -> JsonValue;
101    /// 判断表是否存在
102    fn table_is_exist(&mut self, name: &str) -> bool;
103    /// 当前表
104    fn table(&mut self, name: &str) -> &mut Self;
105    /// 别名
106    fn change_table(&mut self, name: &str) -> &mut Self;
107
108    /// 主键自增
109    fn autoinc(&mut self) -> &mut Self;
110    /// 返回sql语句
111    fn fetch_sql(&mut self) -> &mut Self;
112    /// 排序
113    fn order(&mut self, field: &str, by: bool) -> &mut Self;
114    /// 分组
115    fn group(&mut self, field: &str) -> &mut Self;
116    /// 消除重复记录
117    fn distinct(&mut self) -> &mut Self;
118    /// JSON 字段
119    fn json(&mut self, field: &str) -> &mut Self;
120    /// location 字段
121    fn location(&mut self, field: &str) -> &mut Self;
122    /// 显示字段
123    fn field(&mut self, field: &str) -> &mut Self;
124    /// 隐藏字段
125    fn hidden(&mut self, name: &str) -> &mut Self;
126    /// 查询
127    fn where_and(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self;
128    fn where_or(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self;
129
130    /// 比较两个列
131    fn where_column(&mut self, field_a: &str, compare: &str, field_b: &str) -> &mut Self;
132    /// 更新指定列
133    fn update_column(&mut self, field_a: &str, compare: &str) -> &mut Self;
134    /// 分页
135    fn page(&mut self, page: i32, limit: i32) -> &mut Self;
136    /// 查询指定列并返回数组
137    fn column(&mut self, field: &str) -> JsonValue;
138    /// 总数量
139    fn count(&mut self) -> JsonValue;
140    /// 最大值
141    fn max(&mut self, field: &str) -> JsonValue;
142    /// 最小值
143    fn min(&mut self, field: &str) -> JsonValue;
144    /// 合计
145    fn sum(&mut self, field: &str) -> JsonValue;
146    /// 平均值
147    fn avg(&mut self, field: &str) -> JsonValue;
148    /// 获取集合
149    fn select(&mut self) -> JsonValue;
150    /// 获取单记录
151    fn find(&mut self) -> JsonValue;
152    /// 获取单一列值
153    fn value(&mut self, field: &str) -> JsonValue;
154    /// 添加
155    fn insert(&mut self, data: JsonValue) -> JsonValue;
156    /// 批量添加
157    fn insert_all(&mut self, data: JsonValue) -> JsonValue;
158
159    /// 更新
160    fn update(&mut self, data: JsonValue) -> JsonValue;
161    /// 批量更新
162    fn update_all(&mut self, data: JsonValue) -> JsonValue;
163    /// 删除
164    fn delete(&mut self) -> JsonValue;
165
166    /// 事务开始
167    fn transaction(&mut self) -> bool;
168    /// 事务提交
169    fn commit(&mut self) -> bool;
170    /// 事务回滚
171    fn rollback(&mut self) -> bool;
172    /// sql语句执行
173    fn sql(&mut self, sql: &str) -> Result<JsonValue, String>;
174    fn sql_execute(&mut self, sql: &str) -> Result<JsonValue, String>;
175    /// 自增
176    fn inc(&mut self, field: &str, num: f64) -> &mut Self;
177    /// 自减
178    fn dec(&mut self, field: &str, num: f64) -> &mut Self;
179
180    /// 构造子查询
181    fn buildsql(&mut self) -> String;
182
183    fn join_fields(&mut self, fields: Vec<&str>) -> &mut Self;
184    /// 连结
185    /// * main_table 主表表名
186    /// * main_fields 主表字段
187    /// * right_table 关联表名
188    /// * right_fields 关联字段名
189    fn join(&mut self, main_table: &str, main_fields: &str, right_table: &str, right_fields: &str) -> &mut Self;
190
191    /// 内连接--用来取交集
192    ///
193    /// * table 链表表名
194    /// * main_fields 主表字段
195    /// * second_fields 附表关联字段
196    fn join_inner(&mut self, table: &str, main_fields: &str, second_fields: &str) -> &mut Self;
197}
198
199#[derive(Clone, Debug)]
200pub struct Params {
201    pub mode: String,
202    pub autoinc: bool,
203    pub table: String,
204    pub where_and: Vec<String>,
205    pub where_or: Vec<String>,
206    pub where_column: String,
207    pub update_column: Vec<String>,
208    pub inc_dec: JsonValue,
209    pub page: i32,
210    pub limit: i32,
211    pub fields: JsonValue,
212    pub top: String,
213    pub top2: String,
214    pub order: JsonValue,
215    pub group: JsonValue,
216    pub distinct: bool,
217    pub json: JsonValue,
218    pub location: JsonValue,
219    pub sql: bool,
220    pub join: Vec<String>,
221    pub join_inner: Vec<String>,
222    pub join_table: String,
223}
224
225impl Params {
226    pub fn default(mode: &str) -> Self {
227        Self {
228            mode: mode.to_string(),
229            autoinc: false,
230            table: "".to_string(),
231            where_and: vec![],
232            where_or: vec![],
233            where_column: "".to_string(),
234            update_column: vec![],
235            inc_dec: object! {},
236            page: -1,
237            limit: 10,
238            fields: object! {},
239            top: String::new(),
240            top2: String::new(),
241            order: object! {},
242            group: object! {},
243            distinct: false,
244            json: object! {},
245            location: object! {},
246            sql: false,
247            join: Vec::new(),
248            join_inner: Vec::new(),
249            join_table: "".to_string(),
250        }
251    }
252    pub fn where_sql(&mut self) -> String {
253        let mut where_and_sql = vec![];
254        let mut where_or_sql = vec![];
255        let mut sql = vec![];
256
257        for item in self.where_or.iter() {
258            where_or_sql.push(item.clone());
259        }
260        if !where_or_sql.is_empty() {
261            sql.push(format!(" ( {} ) ", where_or_sql.join(" OR ")));
262        }
263
264        for item in self.where_and.iter() {
265            where_and_sql.push(item.clone());
266        }
267        if !where_and_sql.is_empty() {
268            sql.push(where_and_sql.join(" AND "));
269        }
270
271        if !self.where_column.is_empty() {
272            sql.push(self.where_column.clone());
273        }
274
275        if !sql.is_empty() {
276            return format!("WHERE {}", sql.join(" AND "));
277        }
278        "".to_string()
279    }
280    pub fn page_limit_sql(&mut self) -> String {
281        if self.page == -1 {
282            return "".to_string();
283        }
284        match self.mode.as_str() {
285            "mysql" => {
286                format!("LIMIT {},{}", self.page * self.limit - self.limit, self.limit)
287            }
288            "sqlite" => {
289                format!("LIMIT {} OFFSET {}", self.limit, self.page * self.limit - self.limit)
290            }
291            _ => "".to_string()
292        }
293    }
294    pub fn fields(&mut self) -> String {
295        let mut fields = vec![];
296        for (_, value) in self.fields.entries() {
297            match self.mode.as_str() {
298                "mssql" => {
299                    fields.push(format!("{value}"));
300                }
301                "mysql" => {
302                    if DISABLE_FIELD.contains(&value.as_str().unwrap()) {
303                        fields.push(format!("`{value}`"));
304                    } else {
305                        fields.push(format!("{value}"));
306                    }
307                }
308                _ => {
309                    fields.push(format!("{value}"));
310                }
311            }
312        }
313        let fields = {
314            if fields.is_empty() {
315                "*".into()
316            } else {
317                fields.join(",")
318            }
319        };
320        match self.mode.as_str() {
321            "mysql" => {
322                fields.to_string()
323            }
324            "sqlite" => {
325                fields.to_string()
326            }
327            "mssql" => {
328                fields.to_string()
329            }
330            _ => fields.to_string()
331        }
332    }
333    pub fn top(&mut self) -> String {
334        match self.mode.as_str() {
335            "mssql" => {
336                let wheres = self.where_sql();
337                if !self.top2.is_empty() {
338                    let order = self.order();
339                    if order.is_empty() {
340                        self.top = format!("(select ROW_NUMBER() OVER(ORDER BY rand()) as ROW,* from {} {}) as ", self.table, wheres);
341                    } else {
342                        self.top = format!("(select ROW_NUMBER() OVER({}) as ROW,* from {} {}) as ", order, self.table, wheres);
343                    }
344                    return self.top.to_string();
345                }
346                self.top.to_string()
347            }
348            _ => {
349                "".to_string()
350            }
351        }
352    }
353    pub fn top2(&mut self) -> String {
354        match self.mode.as_str() {
355            "mssql" => {
356                if self.where_and.is_empty() && self.where_or.is_empty() && !self.top2.is_empty() {
357                    return format!("where {}", self.top2);
358                }
359                if (!self.where_and.is_empty() || !self.where_or.is_empty()) && !self.top2.is_empty() {
360                    return format!("AND {}", self.top2);
361                }
362                self.top2.to_string()
363            }
364            _ => {
365                "".to_string()
366            }
367        }
368    }
369    pub fn table(&mut self) -> String {
370        match self.mode.as_str() {
371            "mssql" => {
372                if !self.top2.is_empty() {
373                    return "t".to_string();
374                }
375                self.table.to_string()
376            }
377            _ => {
378                self.table.to_string()
379            }
380        }
381    }
382    pub fn join(&mut self) -> String {
383        match self.mode.as_str() {
384            "mssql" => {
385                self.join.join(" ")
386            }
387            _ => {
388                self.join.join(" ")
389            }
390        }
391    }
392
393    // 当前只匹配了MySQL
394    pub fn join_inner(&mut self) -> String {
395        match self.mode.as_str() {
396            "mysql" => {
397                // 优化字符串拼接:使用 Vec 和 join,避免多次 format!
398                if self.join_inner.is_empty() {
399                    "".to_string()
400                } else {
401                    self.join_inner.join(" ")
402                }
403            }
404            _ => {
405                "".to_string()
406            }
407        }
408    }
409
410
411    pub fn order(&mut self) -> String {
412        let mut sql = vec![];
413        for (field, item) in self.order.entries() {
414            match self.mode.as_str() {
415                "mssql" => {
416                    if DISABLE_FIELD.contains(&field) {
417                        sql.push(format!("[{field}] {item}"));
418                    } else {
419                        sql.push(format!("{field} {item}"));
420                    }
421                }
422
423                "pgsql" => {
424                    if DISABLE_FIELD.contains(&field) {
425                        sql.push(format!("\"{field}\" {item}"));
426                    } else {
427                        sql.push(format!("{field} {item}"));
428                    }
429                }
430                _ => {
431                    if DISABLE_FIELD.contains(&field) {
432                        sql.push(format!("`{field}` {item}"));
433                    } else {
434                        sql.push(format!("{field} {item}"));
435                    }
436                }
437            }
438        }
439        if !sql.is_empty() {
440            return format!("ORDER BY {}", sql.join(","));
441        }
442        "".to_string()
443    }
444    pub fn group(&mut self) -> String {
445        // 预分配容量,减少重新分配
446        let mut sql = Vec::with_capacity(self.group.len());
447        
448        for (_, field) in self.group.entries() {
449            let field_str = field.as_str().unwrap_or("");
450            if DISABLE_FIELD.contains(&field_str) {
451                sql.push(format!("`{}`", field_str));
452            } else if field_str.contains(".") {
453                sql.push(field_str.to_string());
454            } else {
455                sql.push(format!("{}.{}", self.table, field_str));
456            }
457        }
458        if !sql.is_empty() {
459            format!("GROUP BY {}", sql.join(","))
460        } else {
461            "".to_string()
462        }
463    }
464    pub fn distinct(&self) -> String {
465        if self.distinct {
466            "DISTINCT".to_string()
467        } else {
468            "".to_string()
469        }
470    }
471    pub fn select_sql(&mut self) -> String {
472        format!("SELECT {} {} FROM {} {} {} {} {} {} {} {} {}", self.distinct(), self.fields(), self.top(), self.table(), self.join(), self.join_inner(), self.where_sql(), self.top2(), self.group(), self.order(), self.page_limit_sql())
473    }
474}