1use mybatis_sql::ops::AsProxy;
2use mybatis_sql::TEMPLATE;
3use mybatis_util::as_bson;
4use rbson::Bson;
5use std::collections::HashMap;
6use std::fmt::{Debug, Formatter};
7use std::ops::Add;
8
9use serde::{Deserialize, Serialize};
10
11use mybatis_core::convert::StmtConvert;
12use mybatis_core::db::DriverType;
13use mybatis_core::Error;
14
15#[derive(Clone)]
41pub struct Wrapper {
42 pub driver_type: DriverType,
43 pub dml: String,
44 pub sql: String,
45 pub args: Vec<Bson>,
46 pub formats: HashMap<String, String>,
48}
49
50macro_rules! push_sql {
51 ($i:expr,$($v:expr$(,)?)*) => {
52 $($i.push_str($v);)*
53 };
54}
55
56impl Debug for Wrapper {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 let mut formats = HashMap::new();
59 for (k, v) in &self.formats {
60 formats.insert(k.to_string(), v.clone());
61 }
62 f.debug_struct("Wrapper")
63 .field("driver_type", &self.driver_type)
64 .field("sql", &self.sql)
65 .field("args", &self.args)
66 .field("dml", &self.dml)
67 .finish()
69 }
70}
71
72impl Wrapper {
73 pub fn new(driver_type: &DriverType) -> Self {
74 Self {
75 driver_type: driver_type.clone(),
76 dml: "where".to_string(),
77 sql: String::with_capacity(200),
78 args: Vec::with_capacity(5),
79 formats: Default::default(),
80 }
81 }
82
83 pub fn trim_value(mut self, from: &str, to: &str) -> Self {
84 self.sql = self.sql.replace(from, to);
85 self
86 }
87
88 pub fn set_formats(mut self, formats: HashMap<String, String>) -> Self {
89 self.formats = formats;
90 self
91 }
92
93 pub fn set_dml(mut self, dml: &str) -> Self {
94 self.dml = dml.to_string();
95 self
96 }
97
98 pub fn push_wrapper(self, arg: Wrapper) -> Self {
108 self.push(&arg.sql, arg.args)
109 }
110
111 pub fn push(mut self, sql: &str, args: Vec<rbson::Bson>) -> Self {
113 let mut new_sql = sql.to_string();
114 match self.driver_type {
115 DriverType::None => {}
116 DriverType::Mysql => {}
117 DriverType::Postgres | DriverType::Mssql => {
118 let self_arg_len = self.args.len();
119 for index in 0..args.len() {
120 let mut convert_column = String::new();
121 self.driver_type.stmt_convert(index, &mut convert_column);
122
123 let mut convert_column_new = String::new();
124 self.driver_type
125 .stmt_convert(index + args.len(), &mut convert_column_new);
126 new_sql = new_sql.replace(convert_column.as_str(), convert_column_new.as_str());
127 }
128 for index in args.len()..self_arg_len {
129 let mut convert_column = String::new();
130 self.driver_type.stmt_convert(index, &mut convert_column);
131
132 let mut convert_column_new = String::new();
133 self.driver_type
134 .stmt_convert(index + args.len(), &mut convert_column_new);
135
136 println!("{},{}", convert_column, convert_column_new);
137 new_sql = new_sql.replace(convert_column.as_str(), convert_column_new.as_str());
138 }
139 }
140 DriverType::Sqlite => {}
141 }
142 self.sql.push_str(new_sql.as_str());
143 for x in args {
144 self.args.push(x);
145 }
146 self
147 }
148
149 pub fn do_if<'s, F>(self, test: bool, method: F) -> Self
154 where
155 F: FnOnce(Self) -> Self,
156 {
157 if test {
158 return method(self);
159 }
160 return self;
161 }
162
163 pub fn r#if<'s, F>(self, test: bool, method: F) -> Self
168 where
169 F: FnOnce(Self) -> Self,
170 {
171 self.do_if(test, method)
172 }
173
174 pub fn do_if_else<'s, F>(self, test: bool, method_if: F, method_else: fn(Self) -> Self) -> Self
179 where
180 F: FnOnce(Self) -> Self,
181 {
182 if test {
183 return method_if(self);
184 } else {
185 return method_else(self);
186 }
187 }
188
189 pub fn r#if_else<'s, F>(self, test: bool, method_if: F, method_else: fn(Self) -> Self) -> Self
194 where
195 F: FnOnce(Self) -> Self,
196 {
197 self.do_if_else(test, method_if, method_else)
198 }
199
200 pub fn do_match<'s, F>(self, cases: &[(bool, fn(Wrapper) -> Wrapper)], default: F) -> Self
210 where
211 F: FnOnce(Self) -> Self,
212 {
213 for (test, case) in cases {
214 if *test {
215 return case(self);
216 }
217 }
218 return default(self);
219 }
220
221 pub fn set_sql(mut self, sql: &str) -> Self {
222 self.sql = sql.to_string();
223 self
224 }
225
226 pub fn push_sql(mut self, sql: &str) -> Self {
227 self.sql.push_str(sql);
228 self
229 }
230
231 pub fn set_args<T>(mut self, args: &[T]) -> Self
232 where
233 T: Serialize,
234 {
235 let v = as_bson!(args);
236 match v {
237 Bson::Null => {
238 return self;
239 }
240 Bson::Array(ref arr) => {
241 self.args = v.as_array().unwrap_or(&vec![]).to_owned();
242 }
243 _ => {}
244 }
245 self
246 }
247
248 pub fn push_arg<T>(mut self, arg: T) -> Self
249 where
250 T: Serialize,
251 {
252 let v = as_bson!(&arg);
253 self.args.push(v);
254 self
255 }
256
257 pub fn pop_arg(mut self) -> Self {
258 self.args.pop();
259 self
260 }
261
262 pub fn not_allow_add_and_on_end(&self) -> bool {
263 let sql = self.sql.trim_end();
264 if sql.is_empty() {
265 return true;
266 }
267 sql.ends_with(TEMPLATE.r#where.left_space)
268 || sql.ends_with(TEMPLATE.and.left_space)
269 || sql.ends_with(TEMPLATE.or.left_space)
270 || sql.ends_with("(")
271 || sql.ends_with(",")
272 || sql.ends_with("=")
273 || sql.ends_with("+")
274 || sql.ends_with("-")
275 || sql.ends_with("*")
276 || sql.ends_with("/")
277 || sql.ends_with("%")
278 || sql.ends_with("^")
279 || sql.ends_with(">")
280 || sql.ends_with("<")
281 || sql.ends_with("&")
282 || sql.ends_with("|")
283 }
284
285 pub fn and(mut self) -> Self {
287 if !self.not_allow_add_and_on_end() {
288 self.sql.push_str(&TEMPLATE.and.left_right_space);
289 }
290 self
291 }
292
293 pub fn or(mut self) -> Self {
295 if !self.not_allow_add_and_on_end() {
296 self.sql.push_str(&TEMPLATE.or.left_right_space);
297 }
298 self
299 }
300
301 pub fn having(mut self, sql_having: &str) -> Self {
302 self = self.and();
303 push_sql!(self.sql, TEMPLATE.having.value, " ", sql_having);
304 self
305 }
306
307 pub fn all_eq<T>(mut self, arg: T) -> Self
309 where
310 T: Serialize,
311 {
312 self = self.and();
313 let v = as_bson!(&arg);
314 if v.is_null() {
315 return self;
316 }
317 if !v.is_object() {
318 return self;
319 }
320 let map = v.as_document().unwrap();
321 if map.len() == 0 {
322 return self;
323 }
324 self.sql.push_str("(");
325 let len = map.len();
326 let mut index = 0;
327 for (k, v) in map {
328 self = self.eq(k.as_str(), v);
329 if (index + 1) != len {
330 self.sql.push_str(" and ");
331 index += 1;
332 }
333 }
334 self.sql.push_str(")");
335 self
336 }
337
338 pub fn do_format_column(&self, column: &str, data: &mut String) {
340 let source = self.formats.get(column);
341 match source {
342 Some(source) => {
343 *data = source.replace("{}", data);
344 }
345 _ => {}
346 }
347 }
348
349 pub fn eq<T>(mut self, column: &str, obj: T) -> Self
353 where
354 T: Serialize,
355 {
356 self = self.and();
357 let mut convert_column = String::new();
358 self.driver_type
359 .stmt_convert(self.args.len(), &mut convert_column);
360 self.do_format_column(column, &mut convert_column);
361 push_sql!(self.sql, column, " = ", convert_column.as_str(),);
362 self.args.push(as_bson!(&obj));
363 self
364 }
365
366 pub fn ne<T>(mut self, column: &str, obj: T) -> Self
368 where
369 T: Serialize,
370 {
371 self = self.and();
372 let mut convert_column = String::new();
373 self.driver_type
374 .stmt_convert(self.args.len(), &mut convert_column);
375 self.do_format_column(column, &mut convert_column);
376 push_sql!(self.sql, column, " <> ", convert_column.as_str(),);
377 self.args.push(as_bson!(&obj));
378 self
379 }
380
381 pub fn order_by(mut self, is_asc: bool, columns: &[&str]) -> Self {
382 let len = columns.len();
383 if len == 0 {
384 return self;
385 }
386 let mut index = 0;
387 self.sql = self
388 .sql
389 .trim_end()
390 .trim_end_matches(TEMPLATE.r#where.left_space)
391 .trim_end_matches(TEMPLATE.and.left_space)
392 .trim_end_matches(TEMPLATE.or.left_space)
393 .to_string();
394 self.sql.push_str(&TEMPLATE.order_by.left_right_space);
395 for x in columns {
396 if is_asc {
397 push_sql!(self.sql, x, " ", TEMPLATE.asc.value,);
398 } else {
399 push_sql!(self.sql, x, " ", TEMPLATE.desc.value,);
400 }
401 if (index + 1) != len {
402 self.sql.push_str(",");
403 index += 1;
404 }
405 }
406 self.sql.push_str(" ");
407 self
408 }
409
410 pub fn order_bys(mut self, column_asc: &[(&str, bool)]) -> Self {
411 let len = column_asc.len();
412 if len == 0 {
413 return self;
414 }
415 let mut index = 0;
416 self.sql = self
417 .sql
418 .trim_end()
419 .trim_end_matches(TEMPLATE.r#where.left_space)
420 .trim_end_matches(TEMPLATE.and.left_space)
421 .trim_end_matches(TEMPLATE.or.left_space)
422 .to_string();
423 self.sql.push_str(&TEMPLATE.order_by.left_right_space);
424 for (x, is_asc) in column_asc {
425 if *is_asc {
426 push_sql!(self.sql, x, " ", TEMPLATE.asc.value,);
427 } else {
428 push_sql!(self.sql, x, " ", TEMPLATE.desc.value,);
429 }
430 if (index + 1) != len {
431 self.sql.push_str(",");
432 index += 1;
433 }
434 }
435 self.sql.push_str(" ");
436 self
437 }
438
439 pub fn group_by(mut self, columns: &[&str]) -> Self {
440 let len = columns.len();
441 if len == 0 {
442 return self;
443 }
444 let mut index = 0;
445 self.sql = self
446 .sql
447 .trim()
448 .trim_end_matches(TEMPLATE.r#where.left_space)
449 .trim_end_matches(TEMPLATE.and.left_space)
450 .trim_end_matches(TEMPLATE.or.left_space)
451 .to_string();
452 self.sql.push_str(&TEMPLATE.group_by.left_right_space);
453 for x in columns {
454 self.sql.push_str(x);
455 if (index + 1) != len {
456 self.sql.push_str(",");
457 index += 1;
458 }
459 }
460 self.sql.push_str(" ");
461 self
462 }
463
464 pub fn gt<T>(mut self, column: &str, obj: T) -> Self
466 where
467 T: Serialize,
468 {
469 self = self.and();
470 let mut convert_column = String::new();
471 self.driver_type
472 .stmt_convert(self.args.len(), &mut convert_column);
473 self.do_format_column(column, &mut convert_column);
474 push_sql!(self.sql, column, " > ", &convert_column.as_str(),);
475 self.args.push(as_bson!(&obj));
476 self
477 }
478 pub fn ge<T>(mut self, column: &str, obj: T) -> Self
480 where
481 T: Serialize,
482 {
483 self = self.and();
484 let mut convert_column = String::new();
485 self.driver_type
486 .stmt_convert(self.args.len(), &mut convert_column);
487 self.do_format_column(column, &mut convert_column);
488 push_sql!(self.sql, column, " >= ", &convert_column.as_str(),);
489 self.args.push(as_bson!(&obj));
490 self
491 }
492
493 pub fn lt<T>(mut self, column: &str, obj: T) -> Self
495 where
496 T: Serialize,
497 {
498 self = self.and();
499 let mut convert_column = String::new();
500 self.driver_type
501 .stmt_convert(self.args.len(), &mut convert_column);
502 self.do_format_column(column, &mut convert_column);
503 push_sql!(self.sql, column, " < ", &convert_column.as_str(),);
504 self.args.push(as_bson!(&obj));
505 self
506 }
507
508 pub fn le<T>(mut self, column: &str, obj: T) -> Self
510 where
511 T: Serialize,
512 {
513 self = self.and();
514 let mut convert_column = String::new();
515 self.driver_type
516 .stmt_convert(self.args.len(), &mut convert_column);
517 self.do_format_column(column, &mut convert_column);
518 push_sql!(self.sql, column, " <= ", &convert_column.as_str(),);
519 self.args.push(as_bson!(&obj));
520 self
521 }
522
523 pub fn between<T>(mut self, column: &str, min: T, max: T) -> Self
524 where
525 T: Serialize,
526 {
527 self = self.and();
528
529 let mut convert_column = String::new();
530 self.driver_type
531 .stmt_convert(self.args.len(), &mut convert_column);
532 self.do_format_column(column, &mut convert_column);
533 push_sql!(
534 self.sql,
535 column,
536 " ",
537 TEMPLATE.between.value,
538 " ",
539 &convert_column.as_str(),
540 );
541
542 self.args.push(as_bson!(&min));
543
544 let mut convert_column = String::new();
545 self.driver_type
546 .stmt_convert(self.args.len(), &mut convert_column);
547 self.do_format_column(column, &mut convert_column);
548 push_sql!(
549 self.sql,
550 " ",
551 TEMPLATE.and.value,
552 " ",
553 &convert_column.as_str(),
554 );
555
556 self.args.push(as_bson!(&max));
557 self
558 }
559
560 pub fn not_between<T>(mut self, column: &str, min: T, max: T) -> Self
561 where
562 T: Serialize,
563 {
564 self = self.and();
565
566 let mut convert_column = String::new();
567 self.driver_type
568 .stmt_convert(self.args.len(), &mut convert_column);
569 self.do_format_column(column, &mut convert_column);
570 push_sql!(
571 self.sql,
572 column,
573 " ",
574 TEMPLATE.not.value,
575 " ",
576 TEMPLATE.between.value,
577 " ",
578 &convert_column.as_str(),
579 );
580
581 self.args.push(as_bson!(&min));
582
583 let mut convert_column = String::new();
584 self.driver_type
585 .stmt_convert(self.args.len(), &mut convert_column);
586 self.do_format_column(column, &mut convert_column);
587 push_sql!(
588 self.sql,
589 " ",
590 TEMPLATE.and.value,
591 " ",
592 &convert_column.as_str(),
593 );
594
595 self.args.push(as_bson!(&max));
596 self
597 }
598
599 pub fn like<T>(mut self, column: &str, obj: T) -> Self
600 where
601 T: Serialize,
602 {
603 self = self.and();
604 let v = as_bson!(&obj);
605 let mut v_str = String::new();
606 if v.as_str().is_some() {
607 v_str = format!("%{}%", v.as_str().unwrap());
608 } else {
609 v_str = format!("%{}%", v.to_string());
610 }
611
612 let mut convert_column = String::new();
613 self.driver_type
614 .stmt_convert(self.args.len(), &mut convert_column);
615 self.do_format_column(column, &mut convert_column);
616 push_sql!(
617 self.sql,
618 column,
619 " ",
620 TEMPLATE.like.value,
621 " ",
622 &convert_column.as_str(),
623 );
624
625 self.args.push(as_bson!(&v_str));
626 self
627 }
628
629 pub fn like_left<T>(mut self, column: &str, obj: T) -> Self
630 where
631 T: Serialize,
632 {
633 self = self.and();
634 let v = as_bson!(&obj);
635 let mut v_str = String::new();
636 if v.as_str().is_some() {
637 v_str = format!("%{}", v.as_str().unwrap());
638 } else {
639 v_str = format!("%{}", v.to_string());
640 }
641
642 let mut convert_column = String::new();
643 self.driver_type
644 .stmt_convert(self.args.len(), &mut convert_column);
645 self.do_format_column(column, &mut convert_column);
646 push_sql!(
647 self.sql,
648 column,
649 " ",
650 TEMPLATE.like.value,
651 " ",
652 &convert_column.as_str(),
653 );
654
655 self.args.push(as_bson!(&v_str));
656 self
657 }
658
659 pub fn like_right<T>(mut self, column: &str, obj: T) -> Self
660 where
661 T: Serialize,
662 {
663 self = self.and();
664 let v = as_bson!(&obj);
665 let mut v_str = String::new();
666 if v.as_str().is_some() {
667 v_str = format!("{}%", v.as_str().unwrap());
668 } else {
669 v_str = format!("{}%", v.to_string());
670 }
671
672 let mut convert_column = String::new();
673 self.driver_type
674 .stmt_convert(self.args.len(), &mut convert_column);
675 self.do_format_column(column, &mut convert_column);
676 push_sql!(
677 self.sql,
678 column,
679 " ",
680 TEMPLATE.like.value,
681 " ",
682 &convert_column.as_str(),
683 );
684
685 self.args.push(as_bson!(&v_str));
686 self
687 }
688
689 pub fn not_like<T>(mut self, column: &str, obj: T) -> Self
690 where
691 T: Serialize,
692 {
693 self = self.and();
694 let v = as_bson!(&obj);
695 let mut v_str = String::new();
696 if v.as_str().is_some() {
697 v_str = format!("%{}%", v.as_str().unwrap());
698 } else {
699 v_str = format!("%{}%", v.to_string());
700 }
701 let mut convert_column = String::new();
702 self.driver_type
703 .stmt_convert(self.args.len(), &mut convert_column);
704 self.do_format_column(column, &mut convert_column);
705 push_sql!(
706 self.sql,
707 column,
708 " ",
709 TEMPLATE.not.value,
710 " ",
711 TEMPLATE.like.value,
712 " ",
713 &convert_column.as_str(),
714 );
715 self.args.push(as_bson!(&v_str));
716 self
717 }
718
719 pub fn is_null(mut self, column: &str) -> Self {
720 self = self.and();
721 self.sql.push_str(column);
722 self.sql.push_str(TEMPLATE.is.left_space);
723 self.sql.push_str(TEMPLATE.null.left_space);
724 self
725 }
726
727 pub fn is_not_null(mut self, column: &str) -> Self {
728 self = self.and();
729 self.sql.push_str(column);
730 self.sql.push_str(TEMPLATE.is.left_space);
731 self.sql.push_str(TEMPLATE.not.left_space);
732 self.sql.push_str(TEMPLATE.null.left_space);
733 self
734 }
735
736 pub fn in_array<T>(mut self, column: &str, obj: &[T]) -> Self
738 where
739 T: Serialize,
740 {
741 if obj.len() == 0 {
742 return self;
743 }
744 self = self.and();
745 push_sql!(self.sql, column, " ", TEMPLATE.r#in.value, " (",);
746 for x in obj {
747 let mut convert_column = String::new();
748 self.driver_type
749 .stmt_convert(self.args.len(), &mut convert_column);
750 self.do_format_column(column, &mut convert_column);
751 push_sql!(self.sql, " ", &convert_column.as_str(), " ",);
752 self.sql.push_str(",");
753 self.args.push(as_bson!(x));
754 }
755 self.sql.pop();
756 push_sql!(self.sql, ")",);
757 self
758 }
759
760 pub fn in_<T>(self, column: &str, obj: &[T]) -> Self
762 where
763 T: Serialize,
764 {
765 self.in_array(column, obj)
766 }
767
768 pub fn r#in<T>(self, column: &str, obj: &[T]) -> Self
770 where
771 T: Serialize,
772 {
773 self.in_array(column, obj)
774 }
775
776 pub fn not_in<T>(mut self, column: &str, obj: &[T]) -> Self
777 where
778 T: Serialize,
779 {
780 if obj.len() == 0 {
781 return self;
782 }
783 self = self.and();
784 push_sql!(
785 self.sql,
786 column,
787 " ",
788 TEMPLATE.not.value,
789 " ",
790 TEMPLATE.r#in.value,
791 " (",
792 );
793 for x in obj {
794 let mut convert_column = String::new();
795 self.driver_type
796 .stmt_convert(self.args.len(), &mut convert_column);
797 self.do_format_column(column, &mut convert_column);
798 push_sql!(self.sql, " ", &convert_column.as_str(), " ",);
799 self.sql.push_str(",");
800 self.args.push(as_bson!(x));
801 }
802 self.sql.pop();
803 push_sql!(self.sql, ")",);
804 self
805 }
806
807 pub fn trim_space(mut self) -> Self {
808 self.sql = self.sql.replace(" ", " ");
809 return self;
810 }
811
812 pub fn trim_and(mut self) -> Self {
813 self.sql = self
814 .sql
815 .trim()
816 .trim_start_matches(TEMPLATE.and.right_space)
817 .trim_end_matches(TEMPLATE.and.left_space)
818 .to_string();
819 self
820 }
821
822 pub fn trim_or(mut self) -> Self {
823 self.sql = self
824 .sql
825 .trim()
826 .trim_start_matches(TEMPLATE.or.right_space)
827 .trim_end_matches(TEMPLATE.or.left_space)
828 .to_owned();
829 self
830 }
831
832 pub fn trim_and_or(mut self) -> Self {
833 self.sql = self
834 .sql
835 .trim()
836 .trim_start_matches(TEMPLATE.and.right_space)
837 .trim_end_matches(TEMPLATE.and.left_space)
838 .trim_start_matches(TEMPLATE.and.right_space)
839 .trim_end_matches(TEMPLATE.and.left_space)
840 .to_owned();
841 self
842 }
843
844 pub fn insert_into(mut self, table_name: &str, columns: &str, values: &str) -> Self {
845 if values.starts_with("(") && values.ends_with(")") {
846 self.sql = format!(
847 "{} {} ({}) {} ({})",
848 TEMPLATE.insert_into.value, table_name, columns, TEMPLATE.values.value, values
849 );
850 } else {
851 self.sql = format!(
852 "{} {} ({}) {} ({})",
853 TEMPLATE.insert_into.value, table_name, columns, TEMPLATE.values.value, values
854 );
855 }
856 self
857 }
858
859 pub fn limit(mut self, limit: u64) -> Self {
863 use std::fmt::Write;
864 push_sql!(self.sql, " ", TEMPLATE.limit.value, " ",);
865 self.sql.write_fmt(format_args!("{}", limit));
866 self.sql.push_str(" ");
867 self
868 }
869}