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::RwLock;
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: RwLock<HashMap<String, Db>> = RwLock::new(HashMap::new());
36 static ref CONNECTION: RwLock<HashMap<String, Connection>> = RwLock::new(HashMap::new());
37 static ref DEFAULT: RwLock<HashMap<usize, String>> = RwLock::new(HashMap::new());
38 static ref TABLE_FIELDS: RwLock<HashMap<String, JsonValue>> = RwLock::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.write() {
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.write() {
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.write() {
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.read() {
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.read() {
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.read() {
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.read() {
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.read() {
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.read() {
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.write() {
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.read() {
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.read() {
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.write() {
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.read() {
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.write() {
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 pub fn having(&mut self, expr: &str) -> &mut Self {
474 match self {
475 #[cfg(feature = "db-mysql")]
476 Db::Mysql(db) => {
477 db.having(expr);
478 }
479 #[cfg(feature = "db-sqlite")]
480 Db::Sqlite(db) => {
481 db.having(expr);
482 }
483 #[cfg(feature = "db-mssql")]
484 Db::Mssql(db) => {
485 db.having(expr);
486 }
487 #[cfg(feature = "db-pgsql")]
488 Db::Pgsql(db) => {
489 db.having(expr);
490 }
491 _ => {}
492 };
493 self
494 }
495
496 pub fn distinct(&mut self) -> &mut Self {
497 match self {
498 #[cfg(feature = "db-mysql")]
499 Db::Mysql(db) => {
500 db.distinct();
501 }
502 #[cfg(feature = "db-sqlite")]
503 Db::Sqlite(db) => {
504 db.distinct();
505 }
506 #[cfg(feature = "db-mssql")]
507 Db::Mssql(db) => {
508 db.distinct();
509 }
510 #[cfg(feature = "db-pgsql")]
511 Db::Pgsql(db) => {
512 db.distinct();
513 }
514 _ => {}
515 }
516 self
517 }
518
519 pub fn json(&mut self, field: &str) -> &mut Self {
520 match self {
521 #[cfg(feature = "db-mysql")]
522 Db::Mysql(db) => {
523 db.json(field);
524 }
525 #[cfg(feature = "db-sqlite")]
526 Db::Sqlite(db) => {
527 db.json(field);
528 }
529 #[cfg(feature = "db-mssql")]
530 Db::Mssql(db) => {
531 db.json(field);
532 }
533 #[cfg(feature = "db-pgsql")]
534 Db::Pgsql(db) => {
535 db.json(field);
536 }
537 _ => {}
538 }
539 self
540 }
541 pub fn location(&mut self, field: &str) -> &mut Self {
543 match self {
544 #[cfg(feature = "db-mysql")]
545 Db::Mysql(db) => {
546 db.location(field);
547 }
548 #[cfg(feature = "db-sqlite")]
549 Db::Sqlite(db) => {
550 db.location(field);
551 }
552 #[cfg(feature = "db-mssql")]
553 Db::Mssql(db) => {
554 db.location(field);
555 }
556 #[cfg(feature = "db-pgsql")]
557 Db::Pgsql(db) => {
558 db.location(field);
559 }
560 _ => {}
561 }
562 self
563 }
564
565 pub fn column(&mut self, field: &str) -> JsonValue {
566 match self {
567 #[cfg(feature = "db-mysql")]
568 Db::Mysql(db) => db.column(field),
569 #[cfg(feature = "db-sqlite")]
570 Db::Sqlite(db) => db.column(field),
571 #[cfg(feature = "db-mssql")]
572 Db::Mssql(db) => db.column(field),
573 #[cfg(feature = "db-pgsql")]
574 Db::Pgsql(db) => db.column(field),
575 _ => object! {},
576 }
577 }
578
579 pub fn where_and(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self {
580 if field.contains("|") {
581 let fields: Vec<&str> = field.split("|").collect();
582 for field in fields.iter() {
583 self.where_or(field.to_string().as_str(), compare, value.clone());
584 }
585 return self;
586 }
587 let compare = compare.to_lowercase();
588 let compare = compare.replace(" ", "");
589 let compare = compare.as_str();
590
591 let value = match &value {
592 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
593 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
594 JsonValue::Array(arr) => JsonValue::Array(
595 arr.iter()
596 .map(|v| match v {
597 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
598 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
599 _ => v.clone(),
600 })
601 .collect(),
602 ),
603 JsonValue::Object(obj) => {
604 let mut new_obj = object::Object::new();
605 for (k, v) in obj.iter() {
606 let vv = match v {
607 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
608 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
609 _ => v.clone(),
610 };
611 new_obj.insert(k, vv);
612 }
613 JsonValue::Object(new_obj)
614 }
615 _ => value.clone(),
616 };
617 match self {
618 #[cfg(feature = "db-mysql")]
619 Db::Mysql(db) => {
620 db.where_and(field, compare, value);
621 }
622 #[cfg(feature = "db-sqlite")]
623 Db::Sqlite(db) => {
624 db.where_and(field, compare, value);
625 }
626 #[cfg(feature = "db-mssql")]
627 Db::Mssql(db) => {
628 db.where_and(field, compare, value);
629 }
630 #[cfg(feature = "db-pgsql")]
631 Db::Pgsql(db) => {
632 db.where_and(field, compare, value);
633 }
634 _ => {}
635 };
636 self
637 }
638
639 pub fn where_or(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self {
640 if field.contains("|") {
641 let fields: Vec<&str> = field.split("|").collect();
642 for field in fields.iter() {
643 self.where_or(field.to_string().as_str(), compare, value.clone());
644 }
645 return self;
646 }
647 let compare = compare.to_lowercase();
648 let compare = compare.replace(" ", "");
649 let compare = compare.as_str();
650
651 let value = match &value {
652 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
653 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
654 JsonValue::Array(arr) => JsonValue::Array(
655 arr.iter()
656 .map(|v| match v {
657 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
658 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
659 _ => v.clone(),
660 })
661 .collect(),
662 ),
663 JsonValue::Object(obj) => {
664 let mut new_obj = object::Object::new();
665 for (k, v) in obj.iter() {
666 let vv = match v {
667 JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
668 JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
669 _ => v.clone(),
670 };
671 new_obj.insert(k, vv);
672 }
673 JsonValue::Object(new_obj)
674 }
675 _ => value.clone(),
676 };
677 match self {
678 #[cfg(feature = "db-mysql")]
679 Db::Mysql(db) => {
680 db.where_or(field, compare, value);
681 }
682 #[cfg(feature = "db-sqlite")]
683 Db::Sqlite(db) => {
684 db.where_or(field, compare, value);
685 }
686 #[cfg(feature = "db-mssql")]
687 Db::Mssql(db) => {
688 db.where_or(field, compare, value);
689 }
690 #[cfg(feature = "db-pgsql")]
691 Db::Pgsql(db) => {
692 db.where_or(field, compare, value);
693 }
694 _ => {}
695 };
696 self
697 }
698 pub fn where_column(&mut self, field_a: &str, compare: &str, field_b: &str) -> &mut Self {
699 match self {
700 #[cfg(feature = "db-mysql")]
701 Db::Mysql(db) => {
702 db.where_column(field_a, compare, field_b);
703 }
704 #[cfg(feature = "db-sqlite")]
705 Db::Sqlite(db) => {
706 db.where_column(field_a, compare, field_b);
707 }
708 #[cfg(feature = "db-mssql")]
709 Db::Mssql(db) => {
710 db.where_column(field_a, compare, field_b);
711 }
712 #[cfg(feature = "db-pgsql")]
713 Db::Pgsql(db) => {
714 db.where_column(field_a, compare, field_b);
715 }
716 _ => {}
717 };
718 self
719 }
720 pub fn where_raw(&mut self, expr: &str) -> &mut Self {
722 match self {
723 #[cfg(feature = "db-mysql")]
724 Db::Mysql(db) => {
725 db.where_raw(expr);
726 }
727 #[cfg(feature = "db-sqlite")]
728 Db::Sqlite(db) => {
729 db.where_raw(expr);
730 }
731 #[cfg(feature = "db-mssql")]
732 Db::Mssql(db) => {
733 db.where_raw(expr);
734 }
735 #[cfg(feature = "db-pgsql")]
736 Db::Pgsql(db) => {
737 db.where_raw(expr);
738 }
739 _ => {}
740 };
741 self
742 }
743 pub fn where_in_sub(&mut self, field: &str, sub_sql: &str) -> &mut Self {
744 match self {
745 #[cfg(feature = "db-mysql")]
746 Db::Mysql(db) => {
747 db.where_in_sub(field, sub_sql);
748 }
749 #[cfg(feature = "db-sqlite")]
750 Db::Sqlite(db) => {
751 db.where_in_sub(field, sub_sql);
752 }
753 #[cfg(feature = "db-mssql")]
754 Db::Mssql(db) => {
755 db.where_in_sub(field, sub_sql);
756 }
757 #[cfg(feature = "db-pgsql")]
758 Db::Pgsql(db) => {
759 db.where_in_sub(field, sub_sql);
760 }
761 _ => {}
762 };
763 self
764 }
765 pub fn where_not_in_sub(&mut self, field: &str, sub_sql: &str) -> &mut Self {
766 match self {
767 #[cfg(feature = "db-mysql")]
768 Db::Mysql(db) => {
769 db.where_not_in_sub(field, sub_sql);
770 }
771 #[cfg(feature = "db-sqlite")]
772 Db::Sqlite(db) => {
773 db.where_not_in_sub(field, sub_sql);
774 }
775 #[cfg(feature = "db-mssql")]
776 Db::Mssql(db) => {
777 db.where_not_in_sub(field, sub_sql);
778 }
779 #[cfg(feature = "db-pgsql")]
780 Db::Pgsql(db) => {
781 db.where_not_in_sub(field, sub_sql);
782 }
783 _ => {}
784 };
785 self
786 }
787 pub fn where_exists(&mut self, sub_sql: &str) -> &mut Self {
788 match self {
789 #[cfg(feature = "db-mysql")]
790 Db::Mysql(db) => {
791 db.where_exists(sub_sql);
792 }
793 #[cfg(feature = "db-sqlite")]
794 Db::Sqlite(db) => {
795 db.where_exists(sub_sql);
796 }
797 #[cfg(feature = "db-mssql")]
798 Db::Mssql(db) => {
799 db.where_exists(sub_sql);
800 }
801 #[cfg(feature = "db-pgsql")]
802 Db::Pgsql(db) => {
803 db.where_exists(sub_sql);
804 }
805 _ => {}
806 };
807 self
808 }
809 pub fn where_not_exists(&mut self, sub_sql: &str) -> &mut Self {
810 match self {
811 #[cfg(feature = "db-mysql")]
812 Db::Mysql(db) => {
813 db.where_not_exists(sub_sql);
814 }
815 #[cfg(feature = "db-sqlite")]
816 Db::Sqlite(db) => {
817 db.where_not_exists(sub_sql);
818 }
819 #[cfg(feature = "db-mssql")]
820 Db::Mssql(db) => {
821 db.where_not_exists(sub_sql);
822 }
823 #[cfg(feature = "db-pgsql")]
824 Db::Pgsql(db) => {
825 db.where_not_exists(sub_sql);
826 }
827 _ => {}
828 };
829 self
830 }
831 pub fn update_column(&mut self, field_a: &str, compare: &str) -> &mut Self {
832 match self {
833 #[cfg(feature = "db-mysql")]
834 Db::Mysql(db) => {
835 db.update_column(field_a, compare);
836 }
837 #[cfg(feature = "db-sqlite")]
838 Db::Sqlite(db) => {
839 db.update_column(field_a, compare);
840 }
841 #[cfg(feature = "db-mssql")]
842 Db::Mssql(db) => {
843 db.update_column(field_a, compare);
844 }
845 #[cfg(feature = "db-pgsql")]
846 Db::Pgsql(db) => {
847 db.update_column(field_a, compare);
848 }
849 _ => {}
850 };
851 self
852 }
853 pub fn count(&mut self) -> JsonValue {
854 match self {
855 #[cfg(feature = "db-mysql")]
856 Db::Mysql(db) => db.count(),
857 #[cfg(feature = "db-sqlite")]
858 Db::Sqlite(db) => db.count(),
859 #[cfg(feature = "db-mssql")]
860 Db::Mssql(db) => db.count(),
861 #[cfg(feature = "db-pgsql")]
862 Db::Pgsql(db) => db.count(),
863 _ => JsonValue::from(0),
864 }
865 }
866 pub fn max(&mut self, field: &str) -> JsonValue {
867 match self {
868 #[cfg(feature = "db-mysql")]
869 Db::Mysql(db) => db.max(field),
870 #[cfg(feature = "db-sqlite")]
871 Db::Sqlite(db) => db.max(field),
872 #[cfg(feature = "db-mssql")]
873 Db::Mssql(db) => db.max(field),
874 #[cfg(feature = "db-pgsql")]
875 Db::Pgsql(db) => db.max(field),
876 _ => object! {},
877 }
878 }
879
880 pub fn min(&mut self, field: &str) -> JsonValue {
881 match self {
882 #[cfg(feature = "db-mysql")]
883 Db::Mysql(db) => db.min(field),
884 #[cfg(feature = "db-sqlite")]
885 Db::Sqlite(db) => db.min(field),
886 #[cfg(feature = "db-mssql")]
887 Db::Mssql(db) => db.min(field),
888 #[cfg(feature = "db-pgsql")]
889 Db::Pgsql(db) => db.min(field),
890 _ => object! {},
891 }
892 }
893
894 pub fn sum(&mut self, field: &str) -> JsonValue {
895 match self {
896 #[cfg(feature = "db-mysql")]
897 Db::Mysql(db) => db.sum(field),
898 #[cfg(feature = "db-sqlite")]
899 Db::Sqlite(db) => db.sum(field),
900 #[cfg(feature = "db-mssql")]
901 Db::Mssql(db) => db.sum(field),
902 #[cfg(feature = "db-pgsql")]
903 Db::Pgsql(db) => db.sum(field),
904 _ => object! {},
905 }
906 }
907
908 pub fn avg(&mut self, field: &str) -> JsonValue {
909 match self {
910 #[cfg(feature = "db-mysql")]
911 Db::Mysql(db) => db.avg(field),
912 #[cfg(feature = "db-sqlite")]
913 Db::Sqlite(db) => db.avg(field),
914 #[cfg(feature = "db-mssql")]
915 Db::Mssql(db) => db.avg(field),
916 #[cfg(feature = "db-pgsql")]
917 Db::Pgsql(db) => db.avg(field),
918 _ => object! {},
919 }
920 }
921
922 pub fn select(&mut self) -> JsonValue {
923 match self {
924 #[cfg(feature = "db-mysql")]
925 Db::Mysql(db) => db.select(),
926 #[cfg(feature = "db-sqlite")]
927 Db::Sqlite(db) => db.select(),
928 #[cfg(feature = "db-mssql")]
929 Db::Mssql(db) => db.select(),
930 #[cfg(feature = "db-pgsql")]
931 Db::Pgsql(db) => db.select(),
932 _ => object! {},
933 }
934 }
935
936 pub fn find(&mut self) -> JsonValue {
937 match self {
938 #[cfg(feature = "db-mysql")]
939 Db::Mysql(db) => db.find(),
940 #[cfg(feature = "db-sqlite")]
941 Db::Sqlite(db) => db.find(),
942 #[cfg(feature = "db-mssql")]
943 Db::Mssql(db) => db.find(),
944 #[cfg(feature = "db-pgsql")]
945 Db::Pgsql(db) => db.find(),
946 _ => object! {},
947 }
948 }
949
950 pub fn value(&mut self, field: &str) -> JsonValue {
951 match self {
952 #[cfg(feature = "db-mysql")]
953 Db::Mysql(db) => db.value(field),
954 #[cfg(feature = "db-sqlite")]
955 Db::Sqlite(db) => db.value(field),
956 #[cfg(feature = "db-mssql")]
957 Db::Mssql(db) => db.value(field),
958 #[cfg(feature = "db-pgsql")]
959 Db::Pgsql(db) => db.value(field),
960 _ => Null,
961 }
962 }
963
964 pub fn insert(&mut self, mut data: JsonValue) -> JsonValue {
965 let ts = match self {
966 #[cfg(feature = "db-mysql")]
967 Db::Mysql(db) => db.params.timestamps,
968 #[cfg(feature = "db-sqlite")]
969 Db::Sqlite(db) => db.params.timestamps,
970 #[cfg(feature = "db-mssql")]
971 Db::Mssql(db) => db.params.timestamps,
972 #[cfg(feature = "db-pgsql")]
973 Db::Pgsql(db) => db.params.timestamps,
974 _ => false,
975 };
976 if ts {
977 let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
978 if data["created_at"].is_empty() {
979 data["created_at"] = now.clone().into();
980 }
981 if data["updated_at"].is_empty() {
982 data["updated_at"] = now.into();
983 }
984 }
985 match self {
986 #[cfg(feature = "db-mysql")]
987 Db::Mysql(db) => db.insert(data),
988 #[cfg(feature = "db-sqlite")]
989 Db::Sqlite(db) => db.insert(data),
990 #[cfg(feature = "db-mssql")]
991 Db::Mssql(db) => db.insert(data),
992 #[cfg(feature = "db-pgsql")]
993 Db::Pgsql(db) => db.insert(data),
994 _ => JsonValue::from(""),
995 }
996 }
997
998 pub fn insert_all(&mut self, data: JsonValue) -> JsonValue {
999 let data = if data.is_object() {
1000 JsonValue::from(vec![data])
1001 } else {
1002 data
1003 };
1004 match self {
1005 #[cfg(feature = "db-mysql")]
1006 Db::Mysql(db) => db.insert_all(data.clone()),
1007 #[cfg(feature = "db-sqlite")]
1008 Db::Sqlite(db) => db.insert_all(data.clone()),
1009 #[cfg(feature = "db-mssql")]
1010 Db::Mssql(db) => db.insert_all(data.clone()),
1011 #[cfg(feature = "db-pgsql")]
1012 Db::Pgsql(db) => db.insert_all(data.clone()),
1013 _ => object! {},
1014 }
1015 }
1016
1017 pub fn upsert(&mut self, data: JsonValue, conflict_fields: Vec<&str>) -> JsonValue {
1018 match self {
1019 #[cfg(feature = "db-mysql")]
1020 Db::Mysql(db) => db.upsert(data.clone(), conflict_fields),
1021 #[cfg(feature = "db-sqlite")]
1022 Db::Sqlite(db) => db.upsert(data.clone(), conflict_fields),
1023 #[cfg(feature = "db-mssql")]
1024 Db::Mssql(db) => db.upsert(data.clone(), conflict_fields),
1025 #[cfg(feature = "db-pgsql")]
1026 Db::Pgsql(db) => db.upsert(data.clone(), conflict_fields),
1027 _ => JsonValue::from(""),
1028 }
1029 }
1030
1031 pub fn page(&mut self, mut page: i32, limit: i32) -> &mut Self {
1032 if page <= 0 {
1033 page = 1;
1034 }
1035 match self {
1036 #[cfg(feature = "db-mysql")]
1037 Db::Mysql(db) => {
1038 db.page(page, limit);
1039 }
1040 #[cfg(feature = "db-sqlite")]
1041 Db::Sqlite(db) => {
1042 db.page(page, limit);
1043 }
1044 #[cfg(feature = "db-mssql")]
1045 Db::Mssql(db) => {
1046 db.page(page, limit);
1047 }
1048 #[cfg(feature = "db-pgsql")]
1049 Db::Pgsql(db) => {
1050 db.page(page, limit);
1051 }
1052 _ => {}
1053 };
1054 self
1055 }
1056
1057 pub fn limit(&mut self, count: i32) -> &mut Self {
1058 match self {
1059 #[cfg(feature = "db-mysql")]
1060 Db::Mysql(db) => {
1061 db.limit(count);
1062 }
1063 #[cfg(feature = "db-sqlite")]
1064 Db::Sqlite(db) => {
1065 db.limit(count);
1066 }
1067 #[cfg(feature = "db-mssql")]
1068 Db::Mssql(db) => {
1069 db.limit(count);
1070 }
1071 #[cfg(feature = "db-pgsql")]
1072 Db::Pgsql(db) => {
1073 db.limit(count);
1074 }
1075 _ => {}
1076 };
1077 self
1078 }
1079
1080 pub fn update(&mut self, mut data: JsonValue) -> JsonValue {
1081 let ts = match self {
1082 #[cfg(feature = "db-mysql")]
1083 Db::Mysql(db) => db.params.timestamps,
1084 #[cfg(feature = "db-sqlite")]
1085 Db::Sqlite(db) => db.params.timestamps,
1086 #[cfg(feature = "db-mssql")]
1087 Db::Mssql(db) => db.params.timestamps,
1088 #[cfg(feature = "db-pgsql")]
1089 Db::Pgsql(db) => db.params.timestamps,
1090 _ => false,
1091 };
1092 if ts {
1093 let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
1094 if data["updated_at"].is_empty() {
1095 data["updated_at"] = now.into();
1096 }
1097 }
1098 match self {
1099 #[cfg(feature = "db-mysql")]
1100 Db::Mysql(db) => db.update(data),
1101 #[cfg(feature = "db-sqlite")]
1102 Db::Sqlite(db) => db.update(data),
1103 #[cfg(feature = "db-mssql")]
1104 Db::Mssql(db) => db.update(data),
1105 #[cfg(feature = "db-pgsql")]
1106 Db::Pgsql(db) => db.update(data),
1107 _ => JsonValue::from(0),
1108 }
1109 }
1110
1111 pub fn update_all(&mut self, data: JsonValue) -> JsonValue {
1112 match self {
1113 #[cfg(feature = "db-mysql")]
1114 Db::Mysql(db) => db.update_all(data.clone()),
1115 #[cfg(feature = "db-sqlite")]
1116 Db::Sqlite(db) => db.update_all(data.clone()),
1117 #[cfg(feature = "db-mssql")]
1118 Db::Mssql(db) => db.update_all(data.clone()),
1119 #[cfg(feature = "db-pgsql")]
1120 Db::Pgsql(db) => db.update_all(data.clone()),
1121 _ => JsonValue::from(0),
1122 }
1123 }
1124
1125 pub fn get_connection(&mut self) -> Connection {
1126 match self {
1127 #[cfg(feature = "db-mysql")]
1128 Db::Mysql(db) => db.connection.clone(),
1129 #[cfg(feature = "db-sqlite")]
1130 Db::Sqlite(db) => db.connection.clone(),
1131 #[cfg(feature = "db-mssql")]
1132 Db::Mssql(db) => db.connection.clone(),
1133 #[cfg(feature = "db-pgsql")]
1134 Db::Pgsql(db) => db.connection.clone(),
1135 _ => Connection::new(""),
1136 }
1137 }
1138 pub fn database_tables(&mut self) -> JsonValue {
1139 match self {
1140 #[cfg(feature = "db-mysql")]
1141 Db::Mysql(db) => db.database_tables(),
1142 #[cfg(feature = "db-sqlite")]
1143 Db::Sqlite(db) => db.database_tables(),
1144 #[cfg(feature = "db-mssql")]
1145 Db::Mssql(db) => db.database_tables(),
1146 #[cfg(feature = "db-pgsql")]
1147 Db::Pgsql(db) => db.database_tables(),
1148 _ => JsonValue::Array(vec![]),
1149 }
1150 }
1151 pub fn database_create(&mut self, name: &str) -> bool {
1152 match self {
1153 #[cfg(feature = "db-mysql")]
1154 Db::Mysql(db) => db.database_create(name),
1155 #[cfg(feature = "db-sqlite")]
1156 Db::Sqlite(db) => db.database_create(name),
1157 #[cfg(feature = "db-mssql")]
1158 Db::Mssql(db) => db.database_create(name),
1159 #[cfg(feature = "db-pgsql")]
1160 Db::Pgsql(db) => db.database_create(name),
1161 _ => false,
1162 }
1163 }
1164 pub fn truncate(&mut self, table: &str) -> bool {
1165 match self {
1166 #[cfg(feature = "db-mysql")]
1167 Db::Mysql(db) => db.truncate(table),
1168 #[cfg(feature = "db-sqlite")]
1169 Db::Sqlite(db) => db.truncate(table),
1170 #[cfg(feature = "db-mssql")]
1171 Db::Mssql(db) => db.truncate(table),
1172 #[cfg(feature = "db-pgsql")]
1173 Db::Pgsql(db) => db.truncate(table),
1174 _ => false,
1175 }
1176 }
1177 pub fn backups(&mut self, filename: &str) -> bool {
1178 match self {
1179 #[cfg(feature = "db-mysql")]
1180 Db::Mysql(db) => {
1181 match Command::new("mysqldump")
1183 .arg("-u")
1184 .arg(db.connection.username.clone())
1185 .arg("-p")
1186 .arg(db.connection.userpass.clone())
1187 .arg(db.connection.database.clone())
1188 .arg(">")
1189 .arg(filename)
1190 .output()
1191 {
1192 Ok(output) => {
1193 if output.status.success() {
1194 info!("数据库备份完成!");
1196 return true;
1197 }
1198 true
1199 }
1200 Err(e) => {
1201 error!("mysqldump 命令执行失败:{e}");
1203 false
1204 }
1205 }
1206 }
1207 #[cfg(feature = "db-sqlite")]
1208 Db::Sqlite(_db) => false,
1209 #[cfg(feature = "db-mssql")]
1210 Db::Mssql(_db) => false,
1211 #[cfg(feature = "db-pgsql")]
1212 Db::Pgsql(_db) => false,
1213 _ => false,
1214 }
1215 }
1216
1217 pub fn delete(&mut self) -> JsonValue {
1218 match self {
1219 #[cfg(feature = "db-mysql")]
1220 Db::Mysql(db) => db.delete(),
1221 #[cfg(feature = "db-sqlite")]
1222 Db::Sqlite(db) => db.delete(),
1223 #[cfg(feature = "db-mssql")]
1224 Db::Mssql(db) => db.delete(),
1225 #[cfg(feature = "db-pgsql")]
1226 Db::Pgsql(db) => db.delete(),
1227 _ => JsonValue::from(0),
1228 }
1229 }
1230 pub fn field(&mut self, name: &str) -> &mut Self {
1231 match self {
1232 #[cfg(feature = "db-mysql")]
1233 Db::Mysql(db) => {
1234 db.field(name);
1235 }
1236 #[cfg(feature = "db-sqlite")]
1237 Db::Sqlite(db) => {
1238 db.field(name);
1239 }
1240 #[cfg(feature = "db-mssql")]
1241 Db::Mssql(db) => {
1242 db.field(name);
1243 }
1244 #[cfg(feature = "db-pgsql")]
1245 Db::Pgsql(db) => {
1246 db.field(name);
1247 }
1248 _ => {}
1249 };
1250 self
1251 }
1252 pub fn field_raw(&mut self, expr: &str) -> &mut Self {
1254 match self {
1255 #[cfg(feature = "db-mysql")]
1256 Db::Mysql(db) => {
1257 db.field_raw(expr);
1258 }
1259 #[cfg(feature = "db-sqlite")]
1260 Db::Sqlite(db) => {
1261 db.field_raw(expr);
1262 }
1263 #[cfg(feature = "db-mssql")]
1264 Db::Mssql(db) => {
1265 db.field_raw(expr);
1266 }
1267 #[cfg(feature = "db-pgsql")]
1268 Db::Pgsql(db) => {
1269 db.field_raw(expr);
1270 }
1271 _ => {}
1272 };
1273 self
1274 }
1275 pub fn hidden(&mut self, name: &str) -> &mut Self {
1276 match self {
1277 #[cfg(feature = "db-mysql")]
1278 Db::Mysql(db) => {
1279 db.hidden(name);
1280 }
1281 #[cfg(feature = "db-sqlite")]
1282 Db::Sqlite(db) => {
1283 db.hidden(name);
1284 }
1285 #[cfg(feature = "db-mssql")]
1286 Db::Mssql(db) => {
1287 db.hidden(name);
1288 }
1289 #[cfg(feature = "db-pgsql")]
1290 Db::Pgsql(db) => {
1291 db.hidden(name);
1292 }
1293 _ => {}
1294 };
1295 self
1296 }
1297
1298 pub fn transaction(&mut self) -> bool {
1299 match self {
1300 #[cfg(feature = "db-mysql")]
1301 Db::Mysql(db) => db.transaction(),
1302 #[cfg(feature = "db-sqlite")]
1303 Db::Sqlite(db) => db.transaction(),
1304 #[cfg(feature = "db-mssql")]
1305 Db::Mssql(db) => db.transaction(),
1306 #[cfg(feature = "db-pgsql")]
1307 Db::Pgsql(db) => db.transaction(),
1308 _ => false,
1309 }
1310 }
1311
1312 pub fn commit(&mut self) -> bool {
1313 match self {
1314 #[cfg(feature = "db-mysql")]
1315 Db::Mysql(db) => db.commit(),
1316 #[cfg(feature = "db-sqlite")]
1317 Db::Sqlite(db) => db.commit(),
1318 #[cfg(feature = "db-mssql")]
1319 Db::Mssql(db) => db.commit(),
1320 #[cfg(feature = "db-pgsql")]
1321 Db::Pgsql(db) => db.commit(),
1322 _ => false,
1323 }
1324 }
1325
1326 pub fn rollback(&mut self) -> bool {
1327 match self {
1328 #[cfg(feature = "db-mysql")]
1329 Db::Mysql(db) => db.rollback(),
1330 #[cfg(feature = "db-sqlite")]
1331 Db::Sqlite(db) => db.rollback(),
1332 #[cfg(feature = "db-mssql")]
1333 Db::Mssql(db) => db.rollback(),
1334 #[cfg(feature = "db-pgsql")]
1335 Db::Pgsql(db) => db.rollback(),
1336 _ => false,
1337 }
1338 }
1339
1340 pub fn transaction_fn<F, R>(&mut self, f: F) -> Result<R, String>
1341 where
1342 F: FnOnce(&mut Self) -> Result<R, String>,
1343 {
1344 if !self.transaction() {
1345 return Err("事务开启失败".to_string());
1346 }
1347 match f(self) {
1348 Ok(result) => {
1349 if self.commit() {
1350 Ok(result)
1351 } else {
1352 self.rollback();
1353 Err("事务提交失败".to_string())
1354 }
1355 }
1356 Err(e) => {
1357 self.rollback();
1358 Err(e)
1359 }
1360 }
1361 }
1362
1363 pub fn sql(&mut self, sql: &str) -> Result<JsonValue, String> {
1364 match self {
1365 #[cfg(feature = "db-mysql")]
1366 Db::Mysql(db) => db.sql(sql),
1367 #[cfg(feature = "db-sqlite")]
1368 Db::Sqlite(db) => db.sql(sql),
1369 #[cfg(feature = "db-mssql")]
1370 Db::Mssql(db) => db.sql(sql),
1371 #[cfg(feature = "db-pgsql")]
1372 Db::Pgsql(db) => db.sql(sql),
1373 _ => Err("".to_string()),
1374 }
1375 }
1376
1377 pub fn sql_execute(&mut self, sql: &str) -> Result<JsonValue, String> {
1378 match self {
1379 #[cfg(feature = "db-mysql")]
1380 Db::Mysql(db) => db.sql_execute(sql),
1381 #[cfg(feature = "db-sqlite")]
1382 Db::Sqlite(db) => db.sql_execute(sql),
1383 #[cfg(feature = "db-mssql")]
1384 Db::Mssql(db) => db.sql_execute(sql),
1385 #[cfg(feature = "db-pgsql")]
1386 Db::Pgsql(db) => db.sql_execute(sql),
1387 _ => Err("".to_string()),
1388 }
1389 }
1390
1391 pub fn inc(&mut self, field: &str, num: f64) -> &mut Self {
1393 match self {
1394 #[cfg(feature = "db-mysql")]
1395 Db::Mysql(db) => {
1396 db.inc(field, num);
1397 }
1398 #[cfg(feature = "db-sqlite")]
1399 Db::Sqlite(db) => {
1400 db.inc(field, num);
1401 }
1402 #[cfg(feature = "db-mssql")]
1403 Db::Mssql(db) => {
1404 db.inc(field, num);
1405 }
1406 #[cfg(feature = "db-pgsql")]
1407 Db::Pgsql(db) => {
1408 db.inc(field, num);
1409 }
1410 _ => {}
1411 }
1412 self
1413 }
1414 pub fn dec(&mut self, field: &str, num: f64) -> &mut Self {
1416 match self {
1417 #[cfg(feature = "db-mysql")]
1418 Db::Mysql(db) => {
1419 db.dec(field, num);
1420 }
1421 #[cfg(feature = "db-sqlite")]
1422 Db::Sqlite(db) => {
1423 db.dec(field, num);
1424 }
1425 #[cfg(feature = "db-mssql")]
1426 Db::Mssql(db) => {
1427 db.dec(field, num);
1428 }
1429 #[cfg(feature = "db-pgsql")]
1430 Db::Pgsql(db) => {
1431 db.dec(field, num);
1432 }
1433 _ => {}
1434 }
1435 self
1436 }
1437
1438 pub fn buildsql(&mut self) -> String {
1439 match self {
1440 #[cfg(feature = "db-mysql")]
1441 Db::Mysql(db) => db.buildsql(),
1442 #[cfg(feature = "db-sqlite")]
1443 Db::Sqlite(db) => db.buildsql(),
1444 #[cfg(feature = "db-mssql")]
1445 Db::Mssql(db) => db.buildsql(),
1446 #[cfg(feature = "db-pgsql")]
1447 Db::Pgsql(db) => db.buildsql(),
1448 _ => "".to_string(),
1449 }
1450 }
1451 pub fn join_fields(&mut self, fields: Vec<&str>) -> &mut Self {
1452 match self {
1453 #[cfg(feature = "db-mysql")]
1454 Db::Mysql(db) => {
1455 db.join_fields(fields);
1456 }
1457 #[cfg(feature = "db-sqlite")]
1458 Db::Sqlite(db) => {
1459 db.join_fields(fields);
1460 }
1461 #[cfg(feature = "db-mssql")]
1462 Db::Mssql(db) => {
1463 db.join_fields(fields);
1464 }
1465 #[cfg(feature = "db-pgsql")]
1466 Db::Pgsql(db) => {
1467 db.join_fields(fields);
1468 }
1469 _ => {}
1470 }
1471 self
1472 }
1473 pub fn join(
1480 &mut self,
1481 main_table: &str,
1482 main_fields: &str,
1483 right_table: &str,
1484 right_fields: &str,
1485 ) -> &mut Self {
1486 match self {
1487 #[cfg(feature = "db-mysql")]
1488 Db::Mysql(db) => {
1489 db.join(main_table, main_fields, right_table, right_fields);
1490 }
1491 #[cfg(feature = "db-sqlite")]
1492 Db::Sqlite(db) => {
1493 db.join(main_table, main_fields, right_table, right_fields);
1494 }
1495 #[cfg(feature = "db-mssql")]
1496 Db::Mssql(db) => {
1497 db.join(main_table, main_fields, right_table, right_fields);
1498 }
1499 #[cfg(feature = "db-pgsql")]
1500 Db::Pgsql(db) => {
1501 db.join(main_table, main_fields, right_table, right_fields);
1502 }
1503 _ => {}
1504 }
1505 self
1506 }
1507
1508 pub fn join_inner(&mut self, table: &str, main_fields: &str, second_fields: &str) -> &mut Self {
1514 match self {
1515 #[cfg(feature = "db-mysql")]
1516 Db::Mysql(db) => {
1517 db.join_inner(table, main_fields, second_fields);
1518 }
1519 #[cfg(feature = "db-sqlite")]
1520 Db::Sqlite(db) => {
1521 db.join_inner(table, main_fields, second_fields);
1522 }
1523 #[cfg(feature = "db-mssql")]
1524 Db::Mssql(db) => {
1525 db.join_inner(table, main_fields, second_fields);
1526 }
1527 #[cfg(feature = "db-pgsql")]
1528 Db::Pgsql(db) => {
1529 db.join_inner(table, main_fields, second_fields);
1530 }
1531 _ => {}
1532 }
1533 self
1534 }
1535
1536 pub fn join_right(
1537 &mut self,
1538 main_table: &str,
1539 main_fields: &str,
1540 right_table: &str,
1541 right_fields: &str,
1542 ) -> &mut Self {
1543 match self {
1544 #[cfg(feature = "db-mysql")]
1545 Db::Mysql(db) => {
1546 db.join_right(main_table, main_fields, right_table, right_fields);
1547 }
1548 #[cfg(feature = "db-sqlite")]
1549 Db::Sqlite(db) => {
1550 db.join_right(main_table, main_fields, right_table, right_fields);
1551 }
1552 #[cfg(feature = "db-mssql")]
1553 Db::Mssql(db) => {
1554 db.join_right(main_table, main_fields, right_table, right_fields);
1555 }
1556 #[cfg(feature = "db-pgsql")]
1557 Db::Pgsql(db) => {
1558 db.join_right(main_table, main_fields, right_table, right_fields);
1559 }
1560 _ => {}
1561 }
1562 self
1563 }
1564
1565 pub fn join_full(
1566 &mut self,
1567 main_table: &str,
1568 main_fields: &str,
1569 right_table: &str,
1570 right_fields: &str,
1571 ) -> &mut Self {
1572 match self {
1573 #[cfg(feature = "db-mysql")]
1574 Db::Mysql(db) => {
1575 db.join_full(main_table, main_fields, right_table, right_fields);
1576 }
1577 #[cfg(feature = "db-sqlite")]
1578 Db::Sqlite(db) => {
1579 db.join_full(main_table, main_fields, right_table, right_fields);
1580 }
1581 #[cfg(feature = "db-mssql")]
1582 Db::Mssql(db) => {
1583 db.join_full(main_table, main_fields, right_table, right_fields);
1584 }
1585 #[cfg(feature = "db-pgsql")]
1586 Db::Pgsql(db) => {
1587 db.join_full(main_table, main_fields, right_table, right_fields);
1588 }
1589 _ => {}
1590 }
1591 self
1592 }
1593
1594 pub fn union(&mut self, sub_sql: &str) -> &mut Self {
1595 match self {
1596 #[cfg(feature = "db-mysql")]
1597 Db::Mysql(db) => {
1598 db.union(sub_sql);
1599 }
1600 #[cfg(feature = "db-sqlite")]
1601 Db::Sqlite(db) => {
1602 db.union(sub_sql);
1603 }
1604 #[cfg(feature = "db-mssql")]
1605 Db::Mssql(db) => {
1606 db.union(sub_sql);
1607 }
1608 #[cfg(feature = "db-pgsql")]
1609 Db::Pgsql(db) => {
1610 db.union(sub_sql);
1611 }
1612 _ => {}
1613 };
1614 self
1615 }
1616
1617 pub fn union_all(&mut self, sub_sql: &str) -> &mut Self {
1618 match self {
1619 #[cfg(feature = "db-mysql")]
1620 Db::Mysql(db) => {
1621 db.union_all(sub_sql);
1622 }
1623 #[cfg(feature = "db-sqlite")]
1624 Db::Sqlite(db) => {
1625 db.union_all(sub_sql);
1626 }
1627 #[cfg(feature = "db-mssql")]
1628 Db::Mssql(db) => {
1629 db.union_all(sub_sql);
1630 }
1631 #[cfg(feature = "db-pgsql")]
1632 Db::Pgsql(db) => {
1633 db.union_all(sub_sql);
1634 }
1635 _ => {}
1636 };
1637 self
1638 }
1639
1640 pub fn lock_for_update(&mut self) -> &mut Self {
1641 match self {
1642 #[cfg(feature = "db-mysql")]
1643 Db::Mysql(db) => {
1644 db.lock_for_update();
1645 }
1646 #[cfg(feature = "db-sqlite")]
1647 Db::Sqlite(db) => {
1648 db.lock_for_update();
1649 }
1650 #[cfg(feature = "db-mssql")]
1651 Db::Mssql(db) => {
1652 db.lock_for_update();
1653 }
1654 #[cfg(feature = "db-pgsql")]
1655 Db::Pgsql(db) => {
1656 db.lock_for_update();
1657 }
1658 _ => {}
1659 };
1660 self
1661 }
1662
1663 pub fn lock_for_share(&mut self) -> &mut Self {
1664 match self {
1665 #[cfg(feature = "db-mysql")]
1666 Db::Mysql(db) => {
1667 db.lock_for_share();
1668 }
1669 #[cfg(feature = "db-sqlite")]
1670 Db::Sqlite(db) => {
1671 db.lock_for_share();
1672 }
1673 #[cfg(feature = "db-mssql")]
1674 Db::Mssql(db) => {
1675 db.lock_for_share();
1676 }
1677 #[cfg(feature = "db-pgsql")]
1678 Db::Pgsql(db) => {
1679 db.lock_for_share();
1680 }
1681 _ => {}
1682 };
1683 self
1684 }
1685}
1686
1687#[derive(Clone, Debug)]
1689pub struct Table {
1690 pub version: String,
1691 pub table: String,
1692 pub title: String,
1693 pub primary_key: String,
1694 pub unique: Vec<String>,
1695 pub index: Vec<Vec<String>>,
1696 pub fields: JsonValue,
1697 pub partition: bool,
1698 pub partition_columns: JsonValue,
1699}
1700
1701impl Table {
1702 pub fn to_str(self) -> String {
1703 let data = object! {
1704 version:self.version,
1705 table:self.table,
1706 title:self.title,
1707 primary_key:self.primary_key,
1708 unique:self.unique,
1709 index:self.index,
1710 fields:self.fields,
1711 partition:self.partition,
1712 partition_columns:self.partition_columns,
1713 };
1714 data.to_string()
1715 }
1716 pub fn parse(mut data: JsonValue) -> Table {
1717 let mut unique = vec![];
1718 for item in 0..data["unique"].len() {
1719 let str = data["unique"][item].clone().to_string();
1720 unique.push(str);
1721 }
1722 let mut index = vec![];
1723 for item in data["index"].members_mut() {
1724 let mut row = vec![];
1725 for col in item.members_mut() {
1726 row.push(col.to_string());
1727 }
1728 if !row.is_empty() {
1729 index.push(row);
1730 }
1731 }
1732 Self {
1733 version: data["version"].to_string(),
1734 table: data["table"].to_string(),
1735 title: data["title"].to_string(),
1736 primary_key: data["primary_key"].to_string(),
1737 unique,
1738 index,
1739 fields: data["fields"].clone(),
1740 partition: data["partition"].as_bool().unwrap_or(false),
1741 partition_columns: data["partition_columns"].clone(),
1742 }
1743 }
1744}
1745
1746#[cfg(test)]
1747mod tests {
1748 use super::Table;
1749 use json::{array, object};
1750
1751 fn sample_table() -> Table {
1752 Table {
1753 version: "1.0.0".to_string(),
1754 table: "users".to_string(),
1755 title: "Users".to_string(),
1756 primary_key: "id".to_string(),
1757 unique: vec!["email".to_string(), "phone".to_string()],
1758 index: vec![
1759 vec!["name".to_string()],
1760 vec!["created_at".to_string(), "status".to_string()],
1761 ],
1762 fields: object! {
1763 id: "bigint",
1764 name: "string",
1765 active: true,
1766 },
1767 partition: true,
1768 partition_columns: array!["created_at", "region"],
1769 }
1770 }
1771
1772 fn assert_tables_equal(actual: &Table, expected: &Table) {
1773 assert_eq!(actual.version, expected.version);
1774 assert_eq!(actual.table, expected.table);
1775 assert_eq!(actual.title, expected.title);
1776 assert_eq!(actual.primary_key, expected.primary_key);
1777 assert_eq!(actual.unique, expected.unique);
1778 assert_eq!(actual.index, expected.index);
1779 assert_eq!(actual.fields, expected.fields);
1780 assert_eq!(actual.partition, expected.partition);
1781 assert_eq!(actual.partition_columns, expected.partition_columns);
1782 }
1783
1784 #[test]
1785 fn table_to_str_contains_expected_keys_and_values() {
1786 let json_str = sample_table().to_str();
1787
1788 assert!(json_str.contains("\"version\":\"1.0.0\""));
1789 assert!(json_str.contains("\"table\":\"users\""));
1790 assert!(json_str.contains("\"primary_key\":\"id\""));
1791 assert!(json_str.contains("\"partition\":true"));
1792 assert!(json_str.contains("\"unique\":[\"email\",\"phone\"]"));
1793 assert!(json_str.contains("\"partition_columns\":[\"created_at\",\"region\"]"));
1794 }
1795
1796 #[test]
1797 fn table_parse_reads_all_fields() {
1798 let data = object! {
1799 version: "2.1.3",
1800 table: "orders",
1801 title: "Orders",
1802 primary_key: "order_id",
1803 unique: array!["order_no", "out_trade_no"],
1804 index: array![
1805 array!["user_id"],
1806 array!["created_at", "status"],
1807 ],
1808 fields: object! {
1809 order_id: "bigint",
1810 amount: "decimal",
1811 },
1812 partition: true,
1813 partition_columns: array!["created_at"],
1814 };
1815
1816 let table = Table::parse(data);
1817
1818 assert_eq!(table.version, "2.1.3");
1819 assert_eq!(table.table, "orders");
1820 assert_eq!(table.title, "Orders");
1821 assert_eq!(table.primary_key, "order_id");
1822 assert_eq!(table.unique, vec!["order_no", "out_trade_no"]);
1823 assert_eq!(
1824 table.index,
1825 vec![vec!["user_id"], vec!["created_at", "status"]]
1826 );
1827 assert_eq!(
1828 table.fields,
1829 object! { order_id: "bigint", amount: "decimal" }
1830 );
1831 assert!(table.partition);
1832 assert_eq!(table.partition_columns, array!["created_at"]);
1833 }
1834
1835 #[test]
1836 fn table_roundtrip_to_str_and_parse() {
1837 let original = sample_table();
1838 let json_str = original.clone().to_str();
1839 let parsed_json = json::parse(&json_str).expect("valid table json");
1840 let parsed_table = Table::parse(parsed_json);
1841
1842 assert_tables_equal(&parsed_table, &original);
1843 }
1844
1845 #[test]
1846 fn table_parse_with_missing_fields_uses_defaults() {
1847 let data = object! {};
1848
1849 let table = Table::parse(data);
1850
1851 assert_eq!(table.version, "null");
1852 assert_eq!(table.table, "null");
1853 assert_eq!(table.title, "null");
1854 assert_eq!(table.primary_key, "null");
1855 assert!(table.unique.is_empty());
1856 assert!(table.index.is_empty());
1857 assert_eq!(table.fields, json::JsonValue::Null);
1858 assert!(!table.partition);
1859 assert_eq!(table.partition_columns, json::JsonValue::Null);
1860 }
1861
1862 #[test]
1863 fn table_parse_nested_index_arrays() {
1864 let data = object! {
1865 index: array![
1866 array!["col_a", "col_b"],
1867 array!["col_c"],
1868 ]
1869 };
1870
1871 let table = Table::parse(data);
1872
1873 assert_eq!(table.index, vec![vec!["col_a", "col_b"], vec!["col_c"]]);
1874 }
1875
1876 #[test]
1877 fn table_parse_unique_array() {
1878 let data = object! {
1879 unique: array!["email", "username"]
1880 };
1881
1882 let table = Table::parse(data);
1883
1884 assert_eq!(table.unique, vec!["email", "username"]);
1885 }
1886
1887 #[test]
1888 fn table_parse_partition_and_partition_columns() {
1889 let data = object! {
1890 partition: true,
1891 partition_columns: array!["created_at", "tenant_id"]
1892 };
1893
1894 let table = Table::parse(data);
1895
1896 assert!(table.partition);
1897 assert_eq!(table.partition_columns, array!["created_at", "tenant_id"]);
1898 }
1899}