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