1use chrono::Local;
2use json::Null;
3use lazy_static::lazy_static;
4use std::collections::HashMap;
5use std::fs;
6use std::panic::{self, AssertUnwindSafe};
7#[cfg(any(feature = "db-mysql", feature = "db-sqlite", feature = "db-mssql"))]
8use std::process::Command;
9use std::sync::RwLock;
10use std::vec;
11
12use crate::config::{Config, Connection};
13#[cfg(feature = "db-mssql")]
14use crate::types::mssql::Mssql;
15#[cfg(feature = "db-mysql")]
16use crate::types::mysql::Mysql;
17#[cfg(feature = "db-pgsql")]
18use crate::types::pgsql::Pgsql;
19#[cfg(feature = "db-sqlite")]
20use crate::types::sqlite::Sqlite;
21use crate::types::Mode;
22use crate::types::{DbMode, TableOptions};
23use json::object;
24use json::JsonValue;
25use log::{error, info};
26
27pub mod config;
28pub mod error;
29pub mod fields;
30pub mod pools;
31pub mod types;
32
33pub use error::{DbError, DbResult};
34
35lazy_static! {
36 pub static ref DB: RwLock<HashMap<String, Db>> = RwLock::new(HashMap::new());
37 static ref CONNECTION: RwLock<HashMap<String, Connection>> = RwLock::new(HashMap::new());
38 static ref DEFAULT: RwLock<HashMap<usize, String>> = RwLock::new(HashMap::new());
39 static ref TABLE_FIELDS: RwLock<HashMap<String, JsonValue>> = RwLock::new(HashMap::new());
40}
41#[derive(Clone)]
42pub enum Db {
43 #[cfg(feature = "db-mysql")]
44 Mysql(Mysql),
45 #[cfg(feature = "db-sqlite")]
46 Sqlite(Sqlite),
47 #[cfg(feature = "db-mssql")]
48 Mssql(Mssql),
49 #[cfg(feature = "db-pgsql")]
50 Pgsql(Pgsql),
51 None,
52}
53
54impl Db {
55 pub fn load(path: &str) -> Result<Db, String> {
56 let conf = fs::read_to_string(path);
57 let t = match conf {
58 Ok(str) => match json::parse(str.as_str()) {
59 Ok(config) => Db::new(Config::from(config))?,
60 Err(_) => Db::new(Config::create(path.into(), false))?,
61 },
62 Err(_) => Db::new(Config::create(path.into(), false))?,
63 };
64 Ok(t)
65 }
66 pub fn new(config: Config) -> Result<Db, String> {
67 let connection = match config.connections.get(&*config.default) {
68 None => return Err(format!("无此配置: {}", config.default)),
69 Some(e) => e,
70 };
71 for (name, conn) in config.connections.clone() {
72 let mut conn_guard = match CONNECTION.write() {
73 Ok(g) => g,
74 Err(e) => e.into_inner(),
75 };
76 if conn_guard.get(&name).is_none() {
77 conn_guard.insert(name, conn);
78 }
79 }
80 {
81 let mut default_guard = match DEFAULT.write() {
82 Ok(g) => g,
83 Err(e) => e.into_inner(),
84 };
85 default_guard.insert(0, config.default.clone());
86 }
87 let db = Db::setlist(connection.clone(), config.default.clone());
88 match db {
89 Ok(db) => {
90 let mut db_guard = match DB.write() {
91 Ok(g) => g,
92 Err(e) => e.into_inner(),
93 };
94 db_guard.insert(config.default.clone(), db);
95 match db_guard.get(&*config.default.clone()) {
96 Some(r) => Ok(r.clone()),
97 None => Err("数据库初始化失败".to_string()),
98 }
99 }
100 Err(e) => Err(e),
101 }
102 }
103
104 fn setlist(mut connection: Connection, default: String) -> Result<Db, String> {
105 match connection.mode.str().as_str() {
106 #[cfg(feature = "db-mysql")]
107 "mysql" => match Mysql::connect(connection.clone(), default.clone()) {
108 Ok(e) => Ok(Db::Mysql(e)),
109 Err(e) => Err(e),
110 },
111 #[cfg(feature = "db-sqlite")]
112 "sqlite" => match Sqlite::connect(connection.clone(), default.clone()) {
113 Ok(e) => Ok(Db::Sqlite(e)),
114 Err(e) => Err(e),
115 },
116 #[cfg(feature = "db-mssql")]
117 "mssql" => match Mssql::connect(connection.clone(), default.clone()) {
118 Ok(e) => Ok(Db::Mssql(e)),
119 Err(e) => Err(e),
120 },
121 #[cfg(feature = "db-pgsql")]
122 "pgsql" => match Pgsql::connect(connection.clone(), default.clone()) {
123 Ok(e) => Ok(Db::Pgsql(e)),
124 Err(e) => Err(e),
125 },
126 _ => Err("未匹配数据库".to_string()),
127 }
128 }
129 pub fn get_config_default(&mut self) -> String {
130 let default_guard = match DEFAULT.read() {
131 Ok(g) => g,
132 Err(e) => e.into_inner(),
133 };
134 match default_guard.get(&0) {
135 Some(d) => d.clone(),
136 None => String::new(),
137 }
138 }
139 pub fn get_config_list(&mut self) -> Vec<String> {
140 let conn_guard = match CONNECTION.read() {
141 Ok(g) => g,
142 Err(e) => e.into_inner(),
143 };
144 conn_guard
145 .iter()
146 .map(|x| x.0.clone())
147 .collect::<Vec<String>>()
148 }
149 pub fn connection(&mut self, name: &str) -> Db {
150 let default_guard = match DEFAULT.read() {
151 Ok(g) => g,
152 Err(e) => e.into_inner(),
153 };
154 let default = match default_guard.get(&0) {
155 Some(d) => d.clone(),
156 None => String::new(),
157 };
158 drop(default_guard);
159
160 let name = if name.is_empty() { &default } else { name };
161
162 let db_guard = match DB.read() {
163 Ok(g) => g,
164 Err(e) => e.into_inner(),
165 };
166 if let Some(db) = db_guard.get(name) {
167 return db.clone();
168 }
169 drop(db_guard);
170
171 let conn_guard = match CONNECTION.read() {
172 Ok(g) => g,
173 Err(e) => e.into_inner(),
174 };
175 let connection = match conn_guard.get(name) {
176 Some(c) => c.clone(),
177 None => {
178 drop(conn_guard);
179 return self.clone();
180 }
181 };
182 drop(conn_guard);
183
184 let db = match Db::setlist(connection, name.to_string()) {
185 Ok(e) => e,
186 Err(_) => {
187 let db_guard = match DB.read() {
188 Ok(g) => g,
189 Err(e) => e.into_inner(),
190 };
191 match db_guard.get(name) {
192 Some(db) => return db.clone(),
193 None => return self.clone(),
194 }
195 }
196 };
197 let mut db_guard = match DB.write() {
198 Ok(g) => g,
199 Err(e) => e.into_inner(),
200 };
201 db_guard.insert(name.to_string(), db.clone());
202 db
203 }
204 pub fn connection_add(&mut self, config_name: &str, connection: Connection) -> Db {
206 let name = if config_name.is_empty() {
207 let default_guard = match DEFAULT.read() {
208 Ok(g) => g,
209 Err(e) => e.into_inner(),
210 };
211 match default_guard.get(&0) {
212 Some(d) => d.clone(),
213 None => String::new(),
214 }
215 } else {
216 config_name.to_string()
217 };
218
219 let db_guard = match DB.read() {
220 Ok(g) => g,
221 Err(e) => e.into_inner(),
222 };
223 if let Some(db) = db_guard.get(&name) {
224 return db.clone();
225 }
226 drop(db_guard);
227
228 {
229 let mut conn_guard = match CONNECTION.write() {
230 Ok(g) => g,
231 Err(e) => e.into_inner(),
232 };
233 conn_guard.insert(name.clone(), connection.clone());
234 }
235
236 let db = match Db::setlist(connection, name.clone()) {
237 Ok(e) => e,
238 Err(_) => {
239 let db_guard = match DB.read() {
240 Ok(g) => g,
241 Err(e) => e.into_inner(),
242 };
243 match db_guard.get(&name) {
244 Some(db) => return db.clone(),
245 None => return self.clone(),
246 }
247 }
248 };
249 let mut db_guard = match DB.write() {
250 Ok(g) => g,
251 Err(e) => e.into_inner(),
252 };
253 db_guard.insert(name, db.clone());
254 db
255 }
256
257 pub fn table_create(&mut self, options: TableOptions) -> JsonValue {
259 match self {
260 #[cfg(feature = "db-mysql")]
261 Db::Mysql(db) => db.table_create(options),
262 #[cfg(feature = "db-sqlite")]
263 Db::Sqlite(db) => db.table_create(options),
264 #[cfg(feature = "db-mssql")]
265 Db::Mssql(_) => JsonValue::from(false),
266 #[cfg(feature = "db-pgsql")]
267 Db::Pgsql(db) => db.table_create(options),
268 _ => JsonValue::from(false),
269 }
270 }
271 pub fn table_update(&mut self, options: TableOptions) -> JsonValue {
272 match self {
273 #[cfg(feature = "db-mysql")]
274 Db::Mysql(db) => db.table_update(options),
275 #[cfg(feature = "db-sqlite")]
276 Db::Sqlite(db) => db.table_update(options),
277 #[cfg(feature = "db-mssql")]
278 Db::Mssql(_) => JsonValue::from(false),
279 #[cfg(feature = "db-pgsql")]
280 Db::Pgsql(db) => db.table_update(options),
281 _ => JsonValue::from(false),
282 }
283 }
284 pub fn table_info(&mut self, table: &str) -> JsonValue {
285 match self {
286 #[cfg(feature = "db-mysql")]
287 Db::Mysql(db) => db.table_info(table),
288 #[cfg(feature = "db-sqlite")]
289 Db::Sqlite(db) => db.table_info(table),
290 #[cfg(feature = "db-mssql")]
291 Db::Mssql(db) => db.table_info(table),
292 #[cfg(feature = "db-pgsql")]
293 Db::Pgsql(db) => db.table_info(table),
294 _ => object! {},
295 }
296 }
297 pub fn table_is_exist(&mut self, name: &str) -> bool {
298 match self {
299 #[cfg(feature = "db-mysql")]
300 Db::Mysql(db) => db.table_is_exist(name),
301 #[cfg(feature = "db-sqlite")]
302 Db::Sqlite(db) => db.table_is_exist(name),
303 #[cfg(feature = "db-mssql")]
304 Db::Mssql(db) => db.table_is_exist(name),
305 #[cfg(feature = "db-pgsql")]
306 Db::Pgsql(db) => db.table_is_exist(name),
307 _ => false,
308 }
309 }
310 pub fn table(&mut self, name: &str) -> &mut Self {
311 match self {
312 #[cfg(feature = "db-mysql")]
313 Db::Mysql(db) => {
314 db.table(name);
315 }
316 #[cfg(feature = "db-sqlite")]
317 Db::Sqlite(db) => {
318 db.table(name);
319 }
320 #[cfg(feature = "db-mssql")]
321 Db::Mssql(db) => {
322 db.table(name);
323 }
324 #[cfg(feature = "db-pgsql")]
325 Db::Pgsql(db) => {
326 db.table(name);
327 }
328 _ => {}
329 };
330 self
331 }
332
333 pub fn change_table(&mut self, name: &str) -> &mut Self {
334 match self {
335 #[cfg(feature = "db-mysql")]
336 Db::Mysql(db) => {
337 db.change_table(name);
338 }
339 #[cfg(feature = "db-sqlite")]
340 Db::Sqlite(db) => {
341 db.change_table(name);
342 }
343 #[cfg(feature = "db-mssql")]
344 Db::Mssql(db) => {
345 db.change_table(name);
346 }
347 #[cfg(feature = "db-pgsql")]
348 Db::Pgsql(db) => {
349 db.change_table(name);
350 }
351 _ => {}
352 };
353 self
354 }
355
356 pub fn autoinc(&mut self) -> &mut Self {
357 match self {
358 #[cfg(feature = "db-mysql")]
359 Db::Mysql(db) => {
360 db.autoinc();
361 }
362 #[cfg(feature = "db-sqlite")]
363 Db::Sqlite(db) => {
364 db.autoinc();
365 }
366 #[cfg(feature = "db-mssql")]
367 Db::Mssql(db) => {
368 db.autoinc();
369 }
370 #[cfg(feature = "db-pgsql")]
371 Db::Pgsql(db) => {
372 db.autoinc();
373 }
374 _ => {}
375 };
376 self
377 }
378
379 pub fn timestamps(&mut self) -> &mut Self {
380 match self {
381 #[cfg(feature = "db-mysql")]
382 Db::Mysql(db) => {
383 db.timestamps();
384 }
385 #[cfg(feature = "db-sqlite")]
386 Db::Sqlite(db) => {
387 db.timestamps();
388 }
389 #[cfg(feature = "db-mssql")]
390 Db::Mssql(db) => {
391 db.timestamps();
392 }
393 #[cfg(feature = "db-pgsql")]
394 Db::Pgsql(db) => {
395 db.timestamps();
396 }
397 _ => {}
398 };
399 self
400 }
401
402 pub fn fetch_sql(&mut self) -> &mut Self {
403 match self {
404 #[cfg(feature = "db-mysql")]
405 Db::Mysql(db) => {
406 db.fetch_sql();
407 }
408 #[cfg(feature = "db-sqlite")]
409 Db::Sqlite(db) => {
410 db.fetch_sql();
411 }
412 #[cfg(feature = "db-mssql")]
413 Db::Mssql(db) => {
414 db.fetch_sql();
415 }
416 #[cfg(feature = "db-pgsql")]
417 Db::Pgsql(db) => {
418 db.fetch_sql();
419 }
420 _ => {}
421 };
422 self
423 }
424 pub fn order(&mut self, field: &str, by: bool) -> &mut Self {
429 match self {
430 #[cfg(feature = "db-mysql")]
431 Db::Mysql(db) => {
432 db.order(field, by);
433 }
434 #[cfg(feature = "db-sqlite")]
435 Db::Sqlite(db) => {
436 db.order(field, by);
437 }
438 #[cfg(feature = "db-mssql")]
439 Db::Mssql(db) => {
440 db.order(field, by);
441 }
442 #[cfg(feature = "db-pgsql")]
443 Db::Pgsql(db) => {
444 db.order(field, by);
445 }
446 _ => {}
447 }
448 self
449 }
450
451 pub fn group(&mut self, field: &str) -> &mut Self {
452 match self {
453 #[cfg(feature = "db-mysql")]
454 Db::Mysql(db) => {
455 db.group(field);
456 }
457 #[cfg(feature = "db-sqlite")]
458 Db::Sqlite(db) => {
459 db.group(field);
460 }
461 #[cfg(feature = "db-mssql")]
462 Db::Mssql(db) => {
463 db.group(field);
464 }
465 #[cfg(feature = "db-pgsql")]
466 Db::Pgsql(db) => {
467 db.group(field);
468 }
469 _ => {}
470 }
471 self
472 }
473 pub fn having(&mut self, expr: &str) -> &mut Self {
475 match self {
476 #[cfg(feature = "db-mysql")]
477 Db::Mysql(db) => {
478 db.having(expr);
479 }
480 #[cfg(feature = "db-sqlite")]
481 Db::Sqlite(db) => {
482 db.having(expr);
483 }
484 #[cfg(feature = "db-mssql")]
485 Db::Mssql(db) => {
486 db.having(expr);
487 }
488 #[cfg(feature = "db-pgsql")]
489 Db::Pgsql(db) => {
490 db.having(expr);
491 }
492 _ => {}
493 };
494 self
495 }
496
497 pub fn distinct(&mut self) -> &mut Self {
498 match self {
499 #[cfg(feature = "db-mysql")]
500 Db::Mysql(db) => {
501 db.distinct();
502 }
503 #[cfg(feature = "db-sqlite")]
504 Db::Sqlite(db) => {
505 db.distinct();
506 }
507 #[cfg(feature = "db-mssql")]
508 Db::Mssql(db) => {
509 db.distinct();
510 }
511 #[cfg(feature = "db-pgsql")]
512 Db::Pgsql(db) => {
513 db.distinct();
514 }
515 _ => {}
516 }
517 self
518 }
519
520 pub fn json(&mut self, field: &str) -> &mut Self {
521 match self {
522 #[cfg(feature = "db-mysql")]
523 Db::Mysql(db) => {
524 db.json(field);
525 }
526 #[cfg(feature = "db-sqlite")]
527 Db::Sqlite(db) => {
528 db.json(field);
529 }
530 #[cfg(feature = "db-mssql")]
531 Db::Mssql(db) => {
532 db.json(field);
533 }
534 #[cfg(feature = "db-pgsql")]
535 Db::Pgsql(db) => {
536 db.json(field);
537 }
538 _ => {}
539 }
540 self
541 }
542 pub fn location(&mut self, field: &str) -> &mut Self {
544 match self {
545 #[cfg(feature = "db-mysql")]
546 Db::Mysql(db) => {
547 db.location(field);
548 }
549 #[cfg(feature = "db-sqlite")]
550 Db::Sqlite(db) => {
551 db.location(field);
552 }
553 #[cfg(feature = "db-mssql")]
554 Db::Mssql(db) => {
555 db.location(field);
556 }
557 #[cfg(feature = "db-pgsql")]
558 Db::Pgsql(db) => {
559 db.location(field);
560 }
561 _ => {}
562 }
563 self
564 }
565
566 pub fn column(&mut self, field: &str) -> JsonValue {
567 match self {
568 #[cfg(feature = "db-mysql")]
569 Db::Mysql(db) => db.column(field),
570 #[cfg(feature = "db-sqlite")]
571 Db::Sqlite(db) => db.column(field),
572 #[cfg(feature = "db-mssql")]
573 Db::Mssql(db) => db.column(field),
574 #[cfg(feature = "db-pgsql")]
575 Db::Pgsql(db) => db.column(field),
576 _ => object! {},
577 }
578 }
579
580 pub fn where_and(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self {
581 if field.contains("|") {
582 let fields: Vec<&str> = field.split("|").collect();
583 for field in fields.iter() {
584 self.where_or(field.to_string().as_str(), compare, value.clone());
585 }
586 return self;
587 }
588 let compare = compare.to_lowercase();
589 let compare = compare.replace(" ", "");
590 let compare = compare.as_str();
591
592 let value = match &value {
593 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
594 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
595 JsonValue::Array(arr) => JsonValue::Array(
596 arr.iter()
597 .map(|v| match v {
598 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
599 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
600 _ => v.clone(),
601 })
602 .collect(),
603 ),
604 JsonValue::Object(obj) => {
605 let mut new_obj = object::Object::new();
606 for (k, v) in obj.iter() {
607 let vv = match v {
608 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
609 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
610 _ => v.clone(),
611 };
612 new_obj.insert(k, vv);
613 }
614 JsonValue::Object(new_obj)
615 }
616 _ => value.clone(),
617 };
618 match self {
619 #[cfg(feature = "db-mysql")]
620 Db::Mysql(db) => {
621 db.where_and(field, compare, value);
622 }
623 #[cfg(feature = "db-sqlite")]
624 Db::Sqlite(db) => {
625 db.where_and(field, compare, value);
626 }
627 #[cfg(feature = "db-mssql")]
628 Db::Mssql(db) => {
629 db.where_and(field, compare, value);
630 }
631 #[cfg(feature = "db-pgsql")]
632 Db::Pgsql(db) => {
633 db.where_and(field, compare, value);
634 }
635 _ => {}
636 };
637 self
638 }
639
640 pub fn where_or(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self {
641 if field.contains("|") {
642 let fields: Vec<&str> = field.split("|").collect();
643 for field in fields.iter() {
644 self.where_or(field.to_string().as_str(), compare, value.clone());
645 }
646 return self;
647 }
648 let compare = compare.to_lowercase();
649 let compare = compare.replace(" ", "");
650 let compare = compare.as_str();
651
652 let value = match &value {
653 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
654 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
655 JsonValue::Array(arr) => JsonValue::Array(
656 arr.iter()
657 .map(|v| match v {
658 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
659 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
660 _ => v.clone(),
661 })
662 .collect(),
663 ),
664 JsonValue::Object(obj) => {
665 let mut new_obj = object::Object::new();
666 for (k, v) in obj.iter() {
667 let vv = match v {
668 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
669 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
670 _ => v.clone(),
671 };
672 new_obj.insert(k, vv);
673 }
674 JsonValue::Object(new_obj)
675 }
676 _ => value.clone(),
677 };
678 match self {
679 #[cfg(feature = "db-mysql")]
680 Db::Mysql(db) => {
681 db.where_or(field, compare, value);
682 }
683 #[cfg(feature = "db-sqlite")]
684 Db::Sqlite(db) => {
685 db.where_or(field, compare, value);
686 }
687 #[cfg(feature = "db-mssql")]
688 Db::Mssql(db) => {
689 db.where_or(field, compare, value);
690 }
691 #[cfg(feature = "db-pgsql")]
692 Db::Pgsql(db) => {
693 db.where_or(field, compare, value);
694 }
695 _ => {}
696 };
697 self
698 }
699 pub fn where_column(&mut self, field_a: &str, compare: &str, field_b: &str) -> &mut Self {
700 match self {
701 #[cfg(feature = "db-mysql")]
702 Db::Mysql(db) => {
703 db.where_column(field_a, compare, field_b);
704 }
705 #[cfg(feature = "db-sqlite")]
706 Db::Sqlite(db) => {
707 db.where_column(field_a, compare, field_b);
708 }
709 #[cfg(feature = "db-mssql")]
710 Db::Mssql(db) => {
711 db.where_column(field_a, compare, field_b);
712 }
713 #[cfg(feature = "db-pgsql")]
714 Db::Pgsql(db) => {
715 db.where_column(field_a, compare, field_b);
716 }
717 _ => {}
718 };
719 self
720 }
721 pub fn where_raw(&mut self, expr: &str) -> &mut Self {
723 match self {
724 #[cfg(feature = "db-mysql")]
725 Db::Mysql(db) => {
726 db.where_raw(expr);
727 }
728 #[cfg(feature = "db-sqlite")]
729 Db::Sqlite(db) => {
730 db.where_raw(expr);
731 }
732 #[cfg(feature = "db-mssql")]
733 Db::Mssql(db) => {
734 db.where_raw(expr);
735 }
736 #[cfg(feature = "db-pgsql")]
737 Db::Pgsql(db) => {
738 db.where_raw(expr);
739 }
740 _ => {}
741 };
742 self
743 }
744 pub fn where_in_sub(&mut self, field: &str, sub_sql: &str) -> &mut Self {
745 match self {
746 #[cfg(feature = "db-mysql")]
747 Db::Mysql(db) => {
748 db.where_in_sub(field, sub_sql);
749 }
750 #[cfg(feature = "db-sqlite")]
751 Db::Sqlite(db) => {
752 db.where_in_sub(field, sub_sql);
753 }
754 #[cfg(feature = "db-mssql")]
755 Db::Mssql(db) => {
756 db.where_in_sub(field, sub_sql);
757 }
758 #[cfg(feature = "db-pgsql")]
759 Db::Pgsql(db) => {
760 db.where_in_sub(field, sub_sql);
761 }
762 _ => {}
763 };
764 self
765 }
766 pub fn where_not_in_sub(&mut self, field: &str, sub_sql: &str) -> &mut Self {
767 match self {
768 #[cfg(feature = "db-mysql")]
769 Db::Mysql(db) => {
770 db.where_not_in_sub(field, sub_sql);
771 }
772 #[cfg(feature = "db-sqlite")]
773 Db::Sqlite(db) => {
774 db.where_not_in_sub(field, sub_sql);
775 }
776 #[cfg(feature = "db-mssql")]
777 Db::Mssql(db) => {
778 db.where_not_in_sub(field, sub_sql);
779 }
780 #[cfg(feature = "db-pgsql")]
781 Db::Pgsql(db) => {
782 db.where_not_in_sub(field, sub_sql);
783 }
784 _ => {}
785 };
786 self
787 }
788 pub fn where_exists(&mut self, sub_sql: &str) -> &mut Self {
789 match self {
790 #[cfg(feature = "db-mysql")]
791 Db::Mysql(db) => {
792 db.where_exists(sub_sql);
793 }
794 #[cfg(feature = "db-sqlite")]
795 Db::Sqlite(db) => {
796 db.where_exists(sub_sql);
797 }
798 #[cfg(feature = "db-mssql")]
799 Db::Mssql(db) => {
800 db.where_exists(sub_sql);
801 }
802 #[cfg(feature = "db-pgsql")]
803 Db::Pgsql(db) => {
804 db.where_exists(sub_sql);
805 }
806 _ => {}
807 };
808 self
809 }
810 pub fn where_not_exists(&mut self, sub_sql: &str) -> &mut Self {
811 match self {
812 #[cfg(feature = "db-mysql")]
813 Db::Mysql(db) => {
814 db.where_not_exists(sub_sql);
815 }
816 #[cfg(feature = "db-sqlite")]
817 Db::Sqlite(db) => {
818 db.where_not_exists(sub_sql);
819 }
820 #[cfg(feature = "db-mssql")]
821 Db::Mssql(db) => {
822 db.where_not_exists(sub_sql);
823 }
824 #[cfg(feature = "db-pgsql")]
825 Db::Pgsql(db) => {
826 db.where_not_exists(sub_sql);
827 }
828 _ => {}
829 };
830 self
831 }
832 pub fn update_column(&mut self, field_a: &str, compare: &str) -> &mut Self {
833 match self {
834 #[cfg(feature = "db-mysql")]
835 Db::Mysql(db) => {
836 db.update_column(field_a, compare);
837 }
838 #[cfg(feature = "db-sqlite")]
839 Db::Sqlite(db) => {
840 db.update_column(field_a, compare);
841 }
842 #[cfg(feature = "db-mssql")]
843 Db::Mssql(db) => {
844 db.update_column(field_a, compare);
845 }
846 #[cfg(feature = "db-pgsql")]
847 Db::Pgsql(db) => {
848 db.update_column(field_a, compare);
849 }
850 _ => {}
851 };
852 self
853 }
854 pub fn count(&mut self) -> JsonValue {
855 match self {
856 #[cfg(feature = "db-mysql")]
857 Db::Mysql(db) => db.count(),
858 #[cfg(feature = "db-sqlite")]
859 Db::Sqlite(db) => db.count(),
860 #[cfg(feature = "db-mssql")]
861 Db::Mssql(db) => db.count(),
862 #[cfg(feature = "db-pgsql")]
863 Db::Pgsql(db) => db.count(),
864 _ => JsonValue::from(0),
865 }
866 }
867 pub fn max(&mut self, field: &str) -> JsonValue {
868 match self {
869 #[cfg(feature = "db-mysql")]
870 Db::Mysql(db) => db.max(field),
871 #[cfg(feature = "db-sqlite")]
872 Db::Sqlite(db) => db.max(field),
873 #[cfg(feature = "db-mssql")]
874 Db::Mssql(db) => db.max(field),
875 #[cfg(feature = "db-pgsql")]
876 Db::Pgsql(db) => db.max(field),
877 _ => object! {},
878 }
879 }
880
881 pub fn min(&mut self, field: &str) -> JsonValue {
882 match self {
883 #[cfg(feature = "db-mysql")]
884 Db::Mysql(db) => db.min(field),
885 #[cfg(feature = "db-sqlite")]
886 Db::Sqlite(db) => db.min(field),
887 #[cfg(feature = "db-mssql")]
888 Db::Mssql(db) => db.min(field),
889 #[cfg(feature = "db-pgsql")]
890 Db::Pgsql(db) => db.min(field),
891 _ => object! {},
892 }
893 }
894
895 pub fn sum(&mut self, field: &str) -> JsonValue {
896 match self {
897 #[cfg(feature = "db-mysql")]
898 Db::Mysql(db) => db.sum(field),
899 #[cfg(feature = "db-sqlite")]
900 Db::Sqlite(db) => db.sum(field),
901 #[cfg(feature = "db-mssql")]
902 Db::Mssql(db) => db.sum(field),
903 #[cfg(feature = "db-pgsql")]
904 Db::Pgsql(db) => db.sum(field),
905 _ => object! {},
906 }
907 }
908
909 pub fn avg(&mut self, field: &str) -> JsonValue {
910 match self {
911 #[cfg(feature = "db-mysql")]
912 Db::Mysql(db) => db.avg(field),
913 #[cfg(feature = "db-sqlite")]
914 Db::Sqlite(db) => db.avg(field),
915 #[cfg(feature = "db-mssql")]
916 Db::Mssql(db) => db.avg(field),
917 #[cfg(feature = "db-pgsql")]
918 Db::Pgsql(db) => db.avg(field),
919 _ => object! {},
920 }
921 }
922
923 pub fn select(&mut self) -> JsonValue {
924 match self {
925 #[cfg(feature = "db-mysql")]
926 Db::Mysql(db) => db.select(),
927 #[cfg(feature = "db-sqlite")]
928 Db::Sqlite(db) => db.select(),
929 #[cfg(feature = "db-mssql")]
930 Db::Mssql(db) => db.select(),
931 #[cfg(feature = "db-pgsql")]
932 Db::Pgsql(db) => db.select(),
933 _ => object! {},
934 }
935 }
936
937 pub fn find(&mut self) -> JsonValue {
938 match self {
939 #[cfg(feature = "db-mysql")]
940 Db::Mysql(db) => db.find(),
941 #[cfg(feature = "db-sqlite")]
942 Db::Sqlite(db) => db.find(),
943 #[cfg(feature = "db-mssql")]
944 Db::Mssql(db) => db.find(),
945 #[cfg(feature = "db-pgsql")]
946 Db::Pgsql(db) => db.find(),
947 _ => object! {},
948 }
949 }
950
951 pub fn value(&mut self, field: &str) -> JsonValue {
952 match self {
953 #[cfg(feature = "db-mysql")]
954 Db::Mysql(db) => db.value(field),
955 #[cfg(feature = "db-sqlite")]
956 Db::Sqlite(db) => db.value(field),
957 #[cfg(feature = "db-mssql")]
958 Db::Mssql(db) => db.value(field),
959 #[cfg(feature = "db-pgsql")]
960 Db::Pgsql(db) => db.value(field),
961 _ => Null,
962 }
963 }
964
965 pub fn insert(&mut self, mut data: JsonValue) -> JsonValue {
966 let ts = match self {
967 #[cfg(feature = "db-mysql")]
968 Db::Mysql(db) => db.params.timestamps,
969 #[cfg(feature = "db-sqlite")]
970 Db::Sqlite(db) => db.params.timestamps,
971 #[cfg(feature = "db-mssql")]
972 Db::Mssql(db) => db.params.timestamps,
973 #[cfg(feature = "db-pgsql")]
974 Db::Pgsql(db) => db.params.timestamps,
975 _ => false,
976 };
977 if ts {
978 let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
979 if data["created_at"].is_empty() {
980 data["created_at"] = now.clone().into();
981 }
982 if data["updated_at"].is_empty() {
983 data["updated_at"] = now.into();
984 }
985 }
986 match self {
987 #[cfg(feature = "db-mysql")]
988 Db::Mysql(db) => db.insert(data),
989 #[cfg(feature = "db-sqlite")]
990 Db::Sqlite(db) => db.insert(data),
991 #[cfg(feature = "db-mssql")]
992 Db::Mssql(db) => db.insert(data),
993 #[cfg(feature = "db-pgsql")]
994 Db::Pgsql(db) => db.insert(data),
995 _ => JsonValue::from(""),
996 }
997 }
998
999 pub fn insert_all(&mut self, data: JsonValue) -> JsonValue {
1000 let data = if data.is_object() {
1001 JsonValue::from(vec![data])
1002 } else {
1003 data
1004 };
1005 match self {
1006 #[cfg(feature = "db-mysql")]
1007 Db::Mysql(db) => db.insert_all(data.clone()),
1008 #[cfg(feature = "db-sqlite")]
1009 Db::Sqlite(db) => db.insert_all(data.clone()),
1010 #[cfg(feature = "db-mssql")]
1011 Db::Mssql(db) => db.insert_all(data.clone()),
1012 #[cfg(feature = "db-pgsql")]
1013 Db::Pgsql(db) => db.insert_all(data.clone()),
1014 _ => object! {},
1015 }
1016 }
1017
1018 pub fn upsert(&mut self, data: JsonValue, conflict_fields: Vec<&str>) -> JsonValue {
1019 match self {
1020 #[cfg(feature = "db-mysql")]
1021 Db::Mysql(db) => db.upsert(data.clone(), conflict_fields),
1022 #[cfg(feature = "db-sqlite")]
1023 Db::Sqlite(db) => db.upsert(data.clone(), conflict_fields),
1024 #[cfg(feature = "db-mssql")]
1025 Db::Mssql(db) => db.upsert(data.clone(), conflict_fields),
1026 #[cfg(feature = "db-pgsql")]
1027 Db::Pgsql(db) => db.upsert(data.clone(), conflict_fields),
1028 _ => JsonValue::from(""),
1029 }
1030 }
1031
1032 pub fn page(&mut self, mut page: i32, limit: i32) -> &mut Self {
1033 if page <= 0 {
1034 page = 1;
1035 }
1036 match self {
1037 #[cfg(feature = "db-mysql")]
1038 Db::Mysql(db) => {
1039 db.page(page, limit);
1040 }
1041 #[cfg(feature = "db-sqlite")]
1042 Db::Sqlite(db) => {
1043 db.page(page, limit);
1044 }
1045 #[cfg(feature = "db-mssql")]
1046 Db::Mssql(db) => {
1047 db.page(page, limit);
1048 }
1049 #[cfg(feature = "db-pgsql")]
1050 Db::Pgsql(db) => {
1051 db.page(page, limit);
1052 }
1053 _ => {}
1054 };
1055 self
1056 }
1057
1058 pub fn limit(&mut self, count: i32) -> &mut Self {
1059 match self {
1060 #[cfg(feature = "db-mysql")]
1061 Db::Mysql(db) => {
1062 db.limit(count);
1063 }
1064 #[cfg(feature = "db-sqlite")]
1065 Db::Sqlite(db) => {
1066 db.limit(count);
1067 }
1068 #[cfg(feature = "db-mssql")]
1069 Db::Mssql(db) => {
1070 db.limit(count);
1071 }
1072 #[cfg(feature = "db-pgsql")]
1073 Db::Pgsql(db) => {
1074 db.limit(count);
1075 }
1076 _ => {}
1077 };
1078 self
1079 }
1080
1081 pub fn update(&mut self, mut data: JsonValue) -> JsonValue {
1082 let ts = match self {
1083 #[cfg(feature = "db-mysql")]
1084 Db::Mysql(db) => db.params.timestamps,
1085 #[cfg(feature = "db-sqlite")]
1086 Db::Sqlite(db) => db.params.timestamps,
1087 #[cfg(feature = "db-mssql")]
1088 Db::Mssql(db) => db.params.timestamps,
1089 #[cfg(feature = "db-pgsql")]
1090 Db::Pgsql(db) => db.params.timestamps,
1091 _ => false,
1092 };
1093 if ts {
1094 let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
1095 if data["updated_at"].is_empty() {
1096 data["updated_at"] = now.into();
1097 }
1098 }
1099 match self {
1100 #[cfg(feature = "db-mysql")]
1101 Db::Mysql(db) => db.update(data),
1102 #[cfg(feature = "db-sqlite")]
1103 Db::Sqlite(db) => db.update(data),
1104 #[cfg(feature = "db-mssql")]
1105 Db::Mssql(db) => db.update(data),
1106 #[cfg(feature = "db-pgsql")]
1107 Db::Pgsql(db) => db.update(data),
1108 _ => JsonValue::from(0),
1109 }
1110 }
1111
1112 pub fn update_all(&mut self, data: JsonValue) -> JsonValue {
1113 match self {
1114 #[cfg(feature = "db-mysql")]
1115 Db::Mysql(db) => db.update_all(data.clone()),
1116 #[cfg(feature = "db-sqlite")]
1117 Db::Sqlite(db) => db.update_all(data.clone()),
1118 #[cfg(feature = "db-mssql")]
1119 Db::Mssql(db) => db.update_all(data.clone()),
1120 #[cfg(feature = "db-pgsql")]
1121 Db::Pgsql(db) => db.update_all(data.clone()),
1122 _ => JsonValue::from(0),
1123 }
1124 }
1125
1126 pub fn get_connection(&mut self) -> Connection {
1127 match self {
1128 #[cfg(feature = "db-mysql")]
1129 Db::Mysql(db) => db.connection.clone(),
1130 #[cfg(feature = "db-sqlite")]
1131 Db::Sqlite(db) => db.connection.clone(),
1132 #[cfg(feature = "db-mssql")]
1133 Db::Mssql(db) => db.connection.clone(),
1134 #[cfg(feature = "db-pgsql")]
1135 Db::Pgsql(db) => db.connection.clone(),
1136 _ => Connection::new(""),
1137 }
1138 }
1139 pub fn database_tables(&mut self) -> JsonValue {
1140 match self {
1141 #[cfg(feature = "db-mysql")]
1142 Db::Mysql(db) => db.database_tables(),
1143 #[cfg(feature = "db-sqlite")]
1144 Db::Sqlite(db) => db.database_tables(),
1145 #[cfg(feature = "db-mssql")]
1146 Db::Mssql(db) => db.database_tables(),
1147 #[cfg(feature = "db-pgsql")]
1148 Db::Pgsql(db) => db.database_tables(),
1149 _ => JsonValue::Array(vec![]),
1150 }
1151 }
1152 pub fn database_create(&mut self, name: &str) -> bool {
1153 match self {
1154 #[cfg(feature = "db-mysql")]
1155 Db::Mysql(db) => db.database_create(name),
1156 #[cfg(feature = "db-sqlite")]
1157 Db::Sqlite(db) => db.database_create(name),
1158 #[cfg(feature = "db-mssql")]
1159 Db::Mssql(db) => db.database_create(name),
1160 #[cfg(feature = "db-pgsql")]
1161 Db::Pgsql(db) => db.database_create(name),
1162 _ => false,
1163 }
1164 }
1165 pub fn truncate(&mut self, table: &str) -> bool {
1166 match self {
1167 #[cfg(feature = "db-mysql")]
1168 Db::Mysql(db) => db.truncate(table),
1169 #[cfg(feature = "db-sqlite")]
1170 Db::Sqlite(db) => db.truncate(table),
1171 #[cfg(feature = "db-mssql")]
1172 Db::Mssql(db) => db.truncate(table),
1173 #[cfg(feature = "db-pgsql")]
1174 Db::Pgsql(db) => db.truncate(table),
1175 _ => false,
1176 }
1177 }
1178 pub fn backups(&mut self, filename: &str) -> bool {
1179 match self {
1180 #[cfg(feature = "db-mysql")]
1181 Db::Mysql(db) => {
1182 match Command::new("mysqldump")
1184 .arg("-u")
1185 .arg(db.connection.username.clone())
1186 .arg("-p")
1187 .arg(db.connection.userpass.clone())
1188 .arg(db.connection.database.clone())
1189 .arg(">")
1190 .arg(filename)
1191 .output()
1192 {
1193 Ok(output) => {
1194 if output.status.success() {
1195 info!("数据库备份完成!");
1197 return true;
1198 }
1199 true
1200 }
1201 Err(e) => {
1202 error!("mysqldump 命令执行失败:{e}");
1204 false
1205 }
1206 }
1207 }
1208 #[cfg(feature = "db-sqlite")]
1209 Db::Sqlite(_db) => false,
1210 #[cfg(feature = "db-mssql")]
1211 Db::Mssql(_db) => false,
1212 #[cfg(feature = "db-pgsql")]
1213 Db::Pgsql(_db) => false,
1214 _ => false,
1215 }
1216 }
1217
1218 pub fn delete(&mut self) -> JsonValue {
1219 match self {
1220 #[cfg(feature = "db-mysql")]
1221 Db::Mysql(db) => db.delete(),
1222 #[cfg(feature = "db-sqlite")]
1223 Db::Sqlite(db) => db.delete(),
1224 #[cfg(feature = "db-mssql")]
1225 Db::Mssql(db) => db.delete(),
1226 #[cfg(feature = "db-pgsql")]
1227 Db::Pgsql(db) => db.delete(),
1228 _ => JsonValue::from(0),
1229 }
1230 }
1231 pub fn field(&mut self, name: &str) -> &mut Self {
1232 match self {
1233 #[cfg(feature = "db-mysql")]
1234 Db::Mysql(db) => {
1235 db.field(name);
1236 }
1237 #[cfg(feature = "db-sqlite")]
1238 Db::Sqlite(db) => {
1239 db.field(name);
1240 }
1241 #[cfg(feature = "db-mssql")]
1242 Db::Mssql(db) => {
1243 db.field(name);
1244 }
1245 #[cfg(feature = "db-pgsql")]
1246 Db::Pgsql(db) => {
1247 db.field(name);
1248 }
1249 _ => {}
1250 };
1251 self
1252 }
1253 pub fn field_raw(&mut self, expr: &str) -> &mut Self {
1255 match self {
1256 #[cfg(feature = "db-mysql")]
1257 Db::Mysql(db) => {
1258 db.field_raw(expr);
1259 }
1260 #[cfg(feature = "db-sqlite")]
1261 Db::Sqlite(db) => {
1262 db.field_raw(expr);
1263 }
1264 #[cfg(feature = "db-mssql")]
1265 Db::Mssql(db) => {
1266 db.field_raw(expr);
1267 }
1268 #[cfg(feature = "db-pgsql")]
1269 Db::Pgsql(db) => {
1270 db.field_raw(expr);
1271 }
1272 _ => {}
1273 };
1274 self
1275 }
1276 pub fn hidden(&mut self, name: &str) -> &mut Self {
1277 match self {
1278 #[cfg(feature = "db-mysql")]
1279 Db::Mysql(db) => {
1280 db.hidden(name);
1281 }
1282 #[cfg(feature = "db-sqlite")]
1283 Db::Sqlite(db) => {
1284 db.hidden(name);
1285 }
1286 #[cfg(feature = "db-mssql")]
1287 Db::Mssql(db) => {
1288 db.hidden(name);
1289 }
1290 #[cfg(feature = "db-pgsql")]
1291 Db::Pgsql(db) => {
1292 db.hidden(name);
1293 }
1294 _ => {}
1295 };
1296 self
1297 }
1298
1299 pub fn transaction(&mut self) -> bool {
1300 match self {
1301 #[cfg(feature = "db-mysql")]
1302 Db::Mysql(db) => db.transaction(),
1303 #[cfg(feature = "db-sqlite")]
1304 Db::Sqlite(db) => db.transaction(),
1305 #[cfg(feature = "db-mssql")]
1306 Db::Mssql(db) => db.transaction(),
1307 #[cfg(feature = "db-pgsql")]
1308 Db::Pgsql(db) => db.transaction(),
1309 _ => false,
1310 }
1311 }
1312
1313 pub fn commit(&mut self) -> bool {
1314 match self {
1315 #[cfg(feature = "db-mysql")]
1316 Db::Mysql(db) => db.commit(),
1317 #[cfg(feature = "db-sqlite")]
1318 Db::Sqlite(db) => db.commit(),
1319 #[cfg(feature = "db-mssql")]
1320 Db::Mssql(db) => db.commit(),
1321 #[cfg(feature = "db-pgsql")]
1322 Db::Pgsql(db) => db.commit(),
1323 _ => false,
1324 }
1325 }
1326
1327 pub fn rollback(&mut self) -> bool {
1328 match self {
1329 #[cfg(feature = "db-mysql")]
1330 Db::Mysql(db) => db.rollback(),
1331 #[cfg(feature = "db-sqlite")]
1332 Db::Sqlite(db) => db.rollback(),
1333 #[cfg(feature = "db-mssql")]
1334 Db::Mssql(db) => db.rollback(),
1335 #[cfg(feature = "db-pgsql")]
1336 Db::Pgsql(db) => db.rollback(),
1337 _ => false,
1338 }
1339 }
1340
1341 pub fn transaction_fn<F, R>(&mut self, f: F) -> Result<R, String>
1342 where
1343 F: FnOnce(&mut Self) -> Result<R, String>,
1344 {
1345 if !self.transaction() {
1346 return Err("事务开启失败".to_string());
1347 }
1348 let result = panic::catch_unwind(AssertUnwindSafe(|| f(self)));
1349 match result {
1350 Ok(Ok(v)) => {
1351 if self.commit() {
1352 Ok(v)
1353 } else {
1354 self.rollback();
1355 Err("事务提交失败".to_string())
1356 }
1357 }
1358 Ok(Err(e)) => {
1359 self.rollback();
1360 Err(e)
1361 }
1362 Err(payload) => {
1363 self.rollback();
1364 panic::resume_unwind(payload);
1365 }
1366 }
1367 }
1368
1369 pub fn sql(&mut self, sql: &str) -> Result<JsonValue, String> {
1370 match self {
1371 #[cfg(feature = "db-mysql")]
1372 Db::Mysql(db) => db.sql(sql),
1373 #[cfg(feature = "db-sqlite")]
1374 Db::Sqlite(db) => db.sql(sql),
1375 #[cfg(feature = "db-mssql")]
1376 Db::Mssql(db) => db.sql(sql),
1377 #[cfg(feature = "db-pgsql")]
1378 Db::Pgsql(db) => db.sql(sql),
1379 _ => Err("".to_string()),
1380 }
1381 }
1382
1383 pub fn sql_execute(&mut self, sql: &str) -> Result<JsonValue, String> {
1384 match self {
1385 #[cfg(feature = "db-mysql")]
1386 Db::Mysql(db) => db.sql_execute(sql),
1387 #[cfg(feature = "db-sqlite")]
1388 Db::Sqlite(db) => db.sql_execute(sql),
1389 #[cfg(feature = "db-mssql")]
1390 Db::Mssql(db) => db.sql_execute(sql),
1391 #[cfg(feature = "db-pgsql")]
1392 Db::Pgsql(db) => db.sql_execute(sql),
1393 _ => Err("".to_string()),
1394 }
1395 }
1396
1397 pub fn inc(&mut self, field: &str, num: f64) -> &mut Self {
1399 match self {
1400 #[cfg(feature = "db-mysql")]
1401 Db::Mysql(db) => {
1402 db.inc(field, num);
1403 }
1404 #[cfg(feature = "db-sqlite")]
1405 Db::Sqlite(db) => {
1406 db.inc(field, num);
1407 }
1408 #[cfg(feature = "db-mssql")]
1409 Db::Mssql(db) => {
1410 db.inc(field, num);
1411 }
1412 #[cfg(feature = "db-pgsql")]
1413 Db::Pgsql(db) => {
1414 db.inc(field, num);
1415 }
1416 _ => {}
1417 }
1418 self
1419 }
1420 pub fn dec(&mut self, field: &str, num: f64) -> &mut Self {
1422 match self {
1423 #[cfg(feature = "db-mysql")]
1424 Db::Mysql(db) => {
1425 db.dec(field, num);
1426 }
1427 #[cfg(feature = "db-sqlite")]
1428 Db::Sqlite(db) => {
1429 db.dec(field, num);
1430 }
1431 #[cfg(feature = "db-mssql")]
1432 Db::Mssql(db) => {
1433 db.dec(field, num);
1434 }
1435 #[cfg(feature = "db-pgsql")]
1436 Db::Pgsql(db) => {
1437 db.dec(field, num);
1438 }
1439 _ => {}
1440 }
1441 self
1442 }
1443
1444 pub fn buildsql(&mut self) -> String {
1445 match self {
1446 #[cfg(feature = "db-mysql")]
1447 Db::Mysql(db) => db.buildsql(),
1448 #[cfg(feature = "db-sqlite")]
1449 Db::Sqlite(db) => db.buildsql(),
1450 #[cfg(feature = "db-mssql")]
1451 Db::Mssql(db) => db.buildsql(),
1452 #[cfg(feature = "db-pgsql")]
1453 Db::Pgsql(db) => db.buildsql(),
1454 _ => "".to_string(),
1455 }
1456 }
1457 pub fn join_fields(&mut self, fields: Vec<&str>) -> &mut Self {
1458 match self {
1459 #[cfg(feature = "db-mysql")]
1460 Db::Mysql(db) => {
1461 db.join_fields(fields);
1462 }
1463 #[cfg(feature = "db-sqlite")]
1464 Db::Sqlite(db) => {
1465 db.join_fields(fields);
1466 }
1467 #[cfg(feature = "db-mssql")]
1468 Db::Mssql(db) => {
1469 db.join_fields(fields);
1470 }
1471 #[cfg(feature = "db-pgsql")]
1472 Db::Pgsql(db) => {
1473 db.join_fields(fields);
1474 }
1475 _ => {}
1476 }
1477 self
1478 }
1479 pub fn join(
1486 &mut self,
1487 main_table: &str,
1488 main_fields: &str,
1489 right_table: &str,
1490 right_fields: &str,
1491 ) -> &mut Self {
1492 match self {
1493 #[cfg(feature = "db-mysql")]
1494 Db::Mysql(db) => {
1495 db.join(main_table, main_fields, right_table, right_fields);
1496 }
1497 #[cfg(feature = "db-sqlite")]
1498 Db::Sqlite(db) => {
1499 db.join(main_table, main_fields, right_table, right_fields);
1500 }
1501 #[cfg(feature = "db-mssql")]
1502 Db::Mssql(db) => {
1503 db.join(main_table, main_fields, right_table, right_fields);
1504 }
1505 #[cfg(feature = "db-pgsql")]
1506 Db::Pgsql(db) => {
1507 db.join(main_table, main_fields, right_table, right_fields);
1508 }
1509 _ => {}
1510 }
1511 self
1512 }
1513
1514 pub fn join_inner(&mut self, table: &str, main_fields: &str, second_fields: &str) -> &mut Self {
1520 match self {
1521 #[cfg(feature = "db-mysql")]
1522 Db::Mysql(db) => {
1523 db.join_inner(table, main_fields, second_fields);
1524 }
1525 #[cfg(feature = "db-sqlite")]
1526 Db::Sqlite(db) => {
1527 db.join_inner(table, main_fields, second_fields);
1528 }
1529 #[cfg(feature = "db-mssql")]
1530 Db::Mssql(db) => {
1531 db.join_inner(table, main_fields, second_fields);
1532 }
1533 #[cfg(feature = "db-pgsql")]
1534 Db::Pgsql(db) => {
1535 db.join_inner(table, main_fields, second_fields);
1536 }
1537 _ => {}
1538 }
1539 self
1540 }
1541
1542 pub fn join_right(
1543 &mut self,
1544 main_table: &str,
1545 main_fields: &str,
1546 right_table: &str,
1547 right_fields: &str,
1548 ) -> &mut Self {
1549 match self {
1550 #[cfg(feature = "db-mysql")]
1551 Db::Mysql(db) => {
1552 db.join_right(main_table, main_fields, right_table, right_fields);
1553 }
1554 #[cfg(feature = "db-sqlite")]
1555 Db::Sqlite(db) => {
1556 db.join_right(main_table, main_fields, right_table, right_fields);
1557 }
1558 #[cfg(feature = "db-mssql")]
1559 Db::Mssql(db) => {
1560 db.join_right(main_table, main_fields, right_table, right_fields);
1561 }
1562 #[cfg(feature = "db-pgsql")]
1563 Db::Pgsql(db) => {
1564 db.join_right(main_table, main_fields, right_table, right_fields);
1565 }
1566 _ => {}
1567 }
1568 self
1569 }
1570
1571 pub fn join_full(
1572 &mut self,
1573 main_table: &str,
1574 main_fields: &str,
1575 right_table: &str,
1576 right_fields: &str,
1577 ) -> &mut Self {
1578 match self {
1579 #[cfg(feature = "db-mysql")]
1580 Db::Mysql(db) => {
1581 db.join_full(main_table, main_fields, right_table, right_fields);
1582 }
1583 #[cfg(feature = "db-sqlite")]
1584 Db::Sqlite(db) => {
1585 db.join_full(main_table, main_fields, right_table, right_fields);
1586 }
1587 #[cfg(feature = "db-mssql")]
1588 Db::Mssql(db) => {
1589 db.join_full(main_table, main_fields, right_table, right_fields);
1590 }
1591 #[cfg(feature = "db-pgsql")]
1592 Db::Pgsql(db) => {
1593 db.join_full(main_table, main_fields, right_table, right_fields);
1594 }
1595 _ => {}
1596 }
1597 self
1598 }
1599
1600 pub fn union(&mut self, sub_sql: &str) -> &mut Self {
1601 match self {
1602 #[cfg(feature = "db-mysql")]
1603 Db::Mysql(db) => {
1604 db.union(sub_sql);
1605 }
1606 #[cfg(feature = "db-sqlite")]
1607 Db::Sqlite(db) => {
1608 db.union(sub_sql);
1609 }
1610 #[cfg(feature = "db-mssql")]
1611 Db::Mssql(db) => {
1612 db.union(sub_sql);
1613 }
1614 #[cfg(feature = "db-pgsql")]
1615 Db::Pgsql(db) => {
1616 db.union(sub_sql);
1617 }
1618 _ => {}
1619 };
1620 self
1621 }
1622
1623 pub fn union_all(&mut self, sub_sql: &str) -> &mut Self {
1624 match self {
1625 #[cfg(feature = "db-mysql")]
1626 Db::Mysql(db) => {
1627 db.union_all(sub_sql);
1628 }
1629 #[cfg(feature = "db-sqlite")]
1630 Db::Sqlite(db) => {
1631 db.union_all(sub_sql);
1632 }
1633 #[cfg(feature = "db-mssql")]
1634 Db::Mssql(db) => {
1635 db.union_all(sub_sql);
1636 }
1637 #[cfg(feature = "db-pgsql")]
1638 Db::Pgsql(db) => {
1639 db.union_all(sub_sql);
1640 }
1641 _ => {}
1642 };
1643 self
1644 }
1645
1646 pub fn lock_for_update(&mut self) -> &mut Self {
1647 match self {
1648 #[cfg(feature = "db-mysql")]
1649 Db::Mysql(db) => {
1650 db.lock_for_update();
1651 }
1652 #[cfg(feature = "db-sqlite")]
1653 Db::Sqlite(db) => {
1654 db.lock_for_update();
1655 }
1656 #[cfg(feature = "db-mssql")]
1657 Db::Mssql(db) => {
1658 db.lock_for_update();
1659 }
1660 #[cfg(feature = "db-pgsql")]
1661 Db::Pgsql(db) => {
1662 db.lock_for_update();
1663 }
1664 _ => {}
1665 };
1666 self
1667 }
1668
1669 pub fn lock_for_share(&mut self) -> &mut Self {
1670 match self {
1671 #[cfg(feature = "db-mysql")]
1672 Db::Mysql(db) => {
1673 db.lock_for_share();
1674 }
1675 #[cfg(feature = "db-sqlite")]
1676 Db::Sqlite(db) => {
1677 db.lock_for_share();
1678 }
1679 #[cfg(feature = "db-mssql")]
1680 Db::Mssql(db) => {
1681 db.lock_for_share();
1682 }
1683 #[cfg(feature = "db-pgsql")]
1684 Db::Pgsql(db) => {
1685 db.lock_for_share();
1686 }
1687 _ => {}
1688 };
1689 self
1690 }
1691}
1692
1693#[derive(Clone, Debug)]
1695pub struct Table {
1696 pub version: String,
1697 pub table: String,
1698 pub title: String,
1699 pub primary_key: String,
1700 pub unique: Vec<String>,
1701 pub index: Vec<Vec<String>>,
1702 pub fields: JsonValue,
1703 pub partition: bool,
1704 pub partition_columns: JsonValue,
1705}
1706
1707impl Table {
1708 pub fn to_str(self) -> String {
1709 let data = object! {
1710 version:self.version,
1711 table:self.table,
1712 title:self.title,
1713 primary_key:self.primary_key,
1714 unique:self.unique,
1715 index:self.index,
1716 fields:self.fields,
1717 partition:self.partition,
1718 partition_columns:self.partition_columns,
1719 };
1720 data.to_string()
1721 }
1722 pub fn parse(mut data: JsonValue) -> Table {
1723 let mut unique = vec![];
1724 for item in 0..data["unique"].len() {
1725 let str = data["unique"][item].clone().to_string();
1726 unique.push(str);
1727 }
1728 let mut index = vec![];
1729 for item in data["index"].members_mut() {
1730 let mut row = vec![];
1731 for col in item.members_mut() {
1732 row.push(col.to_string());
1733 }
1734 if !row.is_empty() {
1735 index.push(row);
1736 }
1737 }
1738 Self {
1739 version: data["version"].to_string(),
1740 table: data["table"].to_string(),
1741 title: data["title"].to_string(),
1742 primary_key: data["primary_key"].to_string(),
1743 unique,
1744 index,
1745 fields: data["fields"].clone(),
1746 partition: data["partition"].as_bool().unwrap_or(false),
1747 partition_columns: data["partition_columns"].clone(),
1748 }
1749 }
1750}
1751
1752#[cfg(test)]
1753mod tests {
1754 use super::Table;
1755 use json::{array, object};
1756
1757 fn sample_table() -> Table {
1758 Table {
1759 version: "1.0.0".to_string(),
1760 table: "users".to_string(),
1761 title: "Users".to_string(),
1762 primary_key: "id".to_string(),
1763 unique: vec!["email".to_string(), "phone".to_string()],
1764 index: vec![
1765 vec!["name".to_string()],
1766 vec!["created_at".to_string(), "status".to_string()],
1767 ],
1768 fields: object! {
1769 id: "bigint",
1770 name: "string",
1771 active: true,
1772 },
1773 partition: true,
1774 partition_columns: array!["created_at", "region"],
1775 }
1776 }
1777
1778 fn assert_tables_equal(actual: &Table, expected: &Table) {
1779 assert_eq!(actual.version, expected.version);
1780 assert_eq!(actual.table, expected.table);
1781 assert_eq!(actual.title, expected.title);
1782 assert_eq!(actual.primary_key, expected.primary_key);
1783 assert_eq!(actual.unique, expected.unique);
1784 assert_eq!(actual.index, expected.index);
1785 assert_eq!(actual.fields, expected.fields);
1786 assert_eq!(actual.partition, expected.partition);
1787 assert_eq!(actual.partition_columns, expected.partition_columns);
1788 }
1789
1790 #[test]
1791 fn table_to_str_contains_expected_keys_and_values() {
1792 let json_str = sample_table().to_str();
1793
1794 assert!(json_str.contains("\"version\":\"1.0.0\""));
1795 assert!(json_str.contains("\"table\":\"users\""));
1796 assert!(json_str.contains("\"primary_key\":\"id\""));
1797 assert!(json_str.contains("\"partition\":true"));
1798 assert!(json_str.contains("\"unique\":[\"email\",\"phone\"]"));
1799 assert!(json_str.contains("\"partition_columns\":[\"created_at\",\"region\"]"));
1800 }
1801
1802 #[test]
1803 fn table_parse_reads_all_fields() {
1804 let data = object! {
1805 version: "2.1.3",
1806 table: "orders",
1807 title: "Orders",
1808 primary_key: "order_id",
1809 unique: array!["order_no", "out_trade_no"],
1810 index: array![
1811 array!["user_id"],
1812 array!["created_at", "status"],
1813 ],
1814 fields: object! {
1815 order_id: "bigint",
1816 amount: "decimal",
1817 },
1818 partition: true,
1819 partition_columns: array!["created_at"],
1820 };
1821
1822 let table = Table::parse(data);
1823
1824 assert_eq!(table.version, "2.1.3");
1825 assert_eq!(table.table, "orders");
1826 assert_eq!(table.title, "Orders");
1827 assert_eq!(table.primary_key, "order_id");
1828 assert_eq!(table.unique, vec!["order_no", "out_trade_no"]);
1829 assert_eq!(
1830 table.index,
1831 vec![vec!["user_id"], vec!["created_at", "status"]]
1832 );
1833 assert_eq!(
1834 table.fields,
1835 object! { order_id: "bigint", amount: "decimal" }
1836 );
1837 assert!(table.partition);
1838 assert_eq!(table.partition_columns, array!["created_at"]);
1839 }
1840
1841 #[test]
1842 fn table_roundtrip_to_str_and_parse() {
1843 let original = sample_table();
1844 let json_str = original.clone().to_str();
1845 let parsed_json = json::parse(&json_str).expect("valid table json");
1846 let parsed_table = Table::parse(parsed_json);
1847
1848 assert_tables_equal(&parsed_table, &original);
1849 }
1850
1851 #[test]
1852 fn table_parse_with_missing_fields_uses_defaults() {
1853 let data = object! {};
1854
1855 let table = Table::parse(data);
1856
1857 assert_eq!(table.version, "null");
1858 assert_eq!(table.table, "null");
1859 assert_eq!(table.title, "null");
1860 assert_eq!(table.primary_key, "null");
1861 assert!(table.unique.is_empty());
1862 assert!(table.index.is_empty());
1863 assert_eq!(table.fields, json::JsonValue::Null);
1864 assert!(!table.partition);
1865 assert_eq!(table.partition_columns, json::JsonValue::Null);
1866 }
1867
1868 #[test]
1869 fn table_parse_nested_index_arrays() {
1870 let data = object! {
1871 index: array![
1872 array!["col_a", "col_b"],
1873 array!["col_c"],
1874 ]
1875 };
1876
1877 let table = Table::parse(data);
1878
1879 assert_eq!(table.index, vec![vec!["col_a", "col_b"], vec!["col_c"]]);
1880 }
1881
1882 #[test]
1883 fn table_parse_unique_array() {
1884 let data = object! {
1885 unique: array!["email", "username"]
1886 };
1887
1888 let table = Table::parse(data);
1889
1890 assert_eq!(table.unique, vec!["email", "username"]);
1891 }
1892
1893 #[test]
1894 fn table_parse_partition_and_partition_columns() {
1895 let data = object! {
1896 partition: true,
1897 partition_columns: array!["created_at", "tenant_id"]
1898 };
1899
1900 let table = Table::parse(data);
1901
1902 assert!(table.partition);
1903 assert_eq!(table.partition_columns, array!["created_at", "tenant_id"]);
1904 }
1905}