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
4pub type DbResult<T> = Result<T, String>;
6
7pub 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
19pub 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 fn database_tables(&mut self) -> JsonValue;
36 fn database_create(&mut self, name: &str) -> bool;
38 fn database_update(&mut self, _name: &str, _options: JsonValue) -> bool {
40 false }
42 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 fn table_info(&mut self, table: &str) -> JsonValue;
104 fn table_is_exist(&mut self, name: &str) -> bool;
106 fn table(&mut self, name: &str) -> &mut Self;
108 fn change_table(&mut self, name: &str) -> &mut Self;
110
111 fn autoinc(&mut self) -> &mut Self;
113 fn fetch_sql(&mut self) -> &mut Self;
115 fn order(&mut self, field: &str, by: bool) -> &mut Self;
117 fn group(&mut self, field: &str) -> &mut Self;
119 fn distinct(&mut self) -> &mut Self;
121 fn json(&mut self, field: &str) -> &mut Self;
123 fn location(&mut self, field: &str) -> &mut Self;
125 fn field(&mut self, field: &str) -> &mut Self;
127 fn hidden(&mut self, name: &str) -> &mut Self;
129 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 fn where_column(&mut self, field_a: &str, compare: &str, field_b: &str) -> &mut Self;
135 fn update_column(&mut self, field_a: &str, compare: &str) -> &mut Self;
137 fn page(&mut self, page: i32, limit: i32) -> &mut Self;
139 fn column(&mut self, field: &str) -> JsonValue;
141 fn count(&mut self) -> JsonValue;
143 fn max(&mut self, field: &str) -> JsonValue;
145 fn min(&mut self, field: &str) -> JsonValue;
147 fn sum(&mut self, field: &str) -> JsonValue;
149 fn avg(&mut self, field: &str) -> JsonValue;
151 fn select(&mut self) -> JsonValue;
153 fn find(&mut self) -> JsonValue;
155 fn value(&mut self, field: &str) -> JsonValue;
157 fn insert(&mut self, data: JsonValue) -> JsonValue;
159 fn insert_all(&mut self, data: JsonValue) -> JsonValue;
161
162 fn update(&mut self, data: JsonValue) -> JsonValue;
164 fn update_all(&mut self, data: JsonValue) -> JsonValue;
166 fn delete(&mut self) -> JsonValue;
168
169 fn transaction(&mut self) -> bool;
171 fn commit(&mut self) -> bool;
173 fn rollback(&mut self) -> bool;
175 fn sql(&mut self, sql: &str) -> Result<JsonValue, String>;
177 fn sql_execute(&mut self, sql: &str) -> Result<JsonValue, String>;
178 fn inc(&mut self, field: &str, num: f64) -> &mut Self;
180 fn dec(&mut self, field: &str, num: f64) -> &mut Self;
182
183 fn buildsql(&mut self) -> String;
185
186 fn join_fields(&mut self, fields: Vec<&str>) -> &mut Self;
187 fn join(&mut self, main_table: &str, main_fields: &str, right_table: &str, right_fields: &str) -> &mut Self;
193
194 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 pub fn join_inner(&mut self) -> String {
398 match self.mode.as_str() {
399 "mysql" => {
400 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 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}