Skip to main content

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