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