1#[derive(Debug, Clone)]
3pub struct QueryBuilder<'a> {
4 pub query: String,
5 pub table: String,
6 pub qtype: QueryType,
7 pub list: Vec<KeywordList>,
8 pub hq: Option<[&'a str; 26]>
9}
10
11impl<'a> QueryBuilder<'a> {
13 pub fn select(fields: Vec<&str>) -> std::result::Result<Self, std::io::Error> {
25 match fields.len() {
26 0 => panic!("you cannot pass an empty vector to the fields argument"),
27 _ => ()
28 }
29
30 let hq = Self::load_hqs();
31 match Self::sanitize_columns(&fields, hq) {
32 Ok(_) => {
33 if fields.len() > 1 && fields[0] == "*" {
34 let query = "SELECT * FROM".to_string();
35
36 return Ok(QueryBuilder {
37 query,
38 table: "".to_string(),
39 qtype: QueryType::Select,
40 list: vec![KeywordList::Select],
41 hq: Some(hq)
42 })
43 } else {
44 let mut query = "SELECT ".to_string();
45
46 let length_of_fields = fields.len();
47
48 for (i , field) in fields.into_iter().enumerate() {
49 if i + 1 == length_of_fields {
50 query = format!("{}{} ", query, field);
51 } else {
52 query = format!("{}{}, ", query, field);
53 }
54 }
55
56 let query = format!("{}FROM", query);
57
58 return Ok(QueryBuilder {
59 query,
60 table: "".to_string(),
61 qtype: QueryType::Select,
62 list: vec![KeywordList::Select],
63 hq: Some(hq)
64 })
65 }
66 },
67 Err(_) => {
68 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "query cannot build because inserted arbitrary query."))
69 }
70 }
71 }
72
73 pub fn delete() -> std::result::Result<Self, std::io::Error> {
85 return Ok(QueryBuilder {
86 query: "DELETE FROM".to_string(),
87 table: "".to_string(),
88 qtype: QueryType::Delete,
89 list: vec![KeywordList::Delete],
90 hq: None
91 })
92 }
93
94 pub fn update() -> std::result::Result<Self, std::io::Error> {
106 return Ok(QueryBuilder {
107 query: "UPDATE".to_string(),
108 table: "".to_string(),
109 qtype: QueryType::Update,
110 list: vec![KeywordList::Update],
111 hq: None
112 })
113 }
114
115 pub fn insert(columns: Vec<&str>, values: Vec<ValueType>) -> std::result::Result<Self, std::io::Error> {
130 match values.len() {
131 0 => panic!("you cannot pass an empty vector to the values argument"),
132 _ => ()
133 }
134
135 let mut query = "INSERT INTO".to_string();
136
137 let hq = Self::load_hqs();
138
139 match QueryBuilder::sanitize_columns(&columns, hq) {
140 Ok(_) => (),
141 Err(_) => {
142 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "query cannot build on insert constructor: because inserted arbitrary query on columns parameter."))
143 }
144 }
145
146 match QueryBuilder::sanitize_inputs(&values, hq) {
147 Ok(_) => (),
148 Err(_) => {
149 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "query cannot build on insert constructor: because inserted arbitrary query in values parameter."))
150
151 }
152 }
153
154 let mut columns_string = "(".to_string();
155 let mut values_string = "(".to_string();
156
157 for (i, column) in columns.into_iter().enumerate() {
158 for (p, value) in values.iter().enumerate() {
159 match i == p {
160 true => {
161 if i == 0 {
162 columns_string = format!("{}{}", columns_string, column);
163 } else {
164 columns_string = format!("{}, {}", columns_string, column);
165 }
166
167 if p == 0 {
168 values_string = format!("{}{}", values_string, value);
169 } else {
170 values_string = format!("{}, {}", values_string, value);
171 }
172 },
173 false => continue
174 }
175 }
176 }
177
178 query = format!("{} {}) VALUES {})", query, columns_string, values_string);
179
180 return Ok(Self {
181 query,
182 table: "".to_string(),
183 qtype: QueryType::Insert,
184 list: vec![KeywordList::Insert],
185 hq: Some(hq)
186 })
187 }
188
189 pub fn table(&mut self, table: &str) -> &mut Self {
201 match self.qtype {
202 QueryType::Select => {
203 self.query = format!("{} {}", self.query, table);
204 self.table = table.to_string();
205 },
206 QueryType::Delete => {
207 self.query = format!("{} {}", self.query, table);
208 self.table = table.to_string()
209 },
210 QueryType::Insert => {
211 let split_the_query = self.query.split(" INTO ").collect::<Vec<&str>>();
212
213 self.query = format!("INSERT INTO {} {}", table, split_the_query[1]);
214 self.table = table.to_string();
215 }
216 QueryType::Update => {
217 self.query = format!("{} {}", self.query, table);
218 self.table = table.to_string()
219 },
220 QueryType::Count => {
221 self.query = format!("{} {}", self.query, table);
222 self.table = table.to_string()
223 }
224 QueryType::Null => panic!("You cannot add a table before you start a query"),
225 QueryType::Create => panic!("You cannot use create keyword with a QueryBuilder instance")
226 }
227
228 self.list.push(KeywordList::Table);
229
230 self
231 }
232
233
234 pub fn count(condition: &str, _as: Option<&str>) -> Self {
246 let query;
247
248 match _as {
249 Some(_as) => query = format!("SELECT COUNT({}) AS {} FROM", condition, _as),
250 None => query = format!("SELECT COUNT({}) FROM", condition)
251 };
252
253 return Self {
254 query,
255 table: "".to_string(),
256 qtype: QueryType::Count,
257 list: vec![KeywordList::Count],
258 hq: Some(Self::load_hqs())
259 }
260 }
261 pub fn where_(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
274 match Self::sanitize_mark(mark) {
275 Ok(_) => (),
276 Err(error) => panic!("{}", error)
277 }
278
279 match self.hq {
280 Some(_) => (),
281 None => self.hq = Some(Self::load_hqs())
282 }
283
284 match self.sanitize_column(&column) {
285 Ok(_) => (),
286 Err(error) => panic!("{}", error)
287 }
288
289 match self.sanitize_input(&value) {
290 Ok(_) => (),
291 Err(error) => panic!("{}", error)
292 }
293
294 self.query = format!("{} WHERE {} {} {}", self.query, column, mark, value);
295
296 self.list.push(KeywordList::Where);
297
298 self
299 }
300
301 pub fn where_in(&mut self, column: &str, ins: &Vec<ValueType>) -> &mut Self {
314 match ins.len() {
315 0 => panic!("you cannot pass an empty vector to the ins argument"),
316 _ => ()
317 }
318
319 self.query = format!("{} WHERE {} IN (", self.query, column);
320
321 let length_of_ins = ins.len();
322
323 for (index, value) in ins.into_iter().enumerate() {
324 if index + 1 == length_of_ins {
325 self.query = format!("{}{})", self.query, value);
326
327 continue;
328 }
329
330 self.query = format!("{}{}, ", self.query, value);
331 }
332
333 self.list.push(KeywordList::In);
334 self
335 }
336
337 pub fn where_not_in(&mut self, column: &str, ins: &Vec<ValueType>) -> &mut Self {
350 match ins.len() {
351 0 => panic!("you cannot pass an empty vector to the ins argument"),
352 _ => ()
353 }
354
355 self.query = format!("{} WHERE {} NOT IN (", self.query, column);
356
357 let length_of_ins = ins.len();
358
359 for (index, value) in ins.into_iter().enumerate() {
360 if index + 1 == length_of_ins {
361 self.query = format!("{}{})", self.query, value);
362
363 continue;
364 }
365
366 self.query = format!("{}{}, ", self.query, value);
367 }
368
369 self.list.push(KeywordList::NotIn);
370 self
371 }
372
373 pub fn where_in_custom(&mut self, column: &str, query: &str) -> &mut Self {
386 self.query = format!("{} WHERE {} IN ({})", self.query, column, query);
387
388 self.list.push(KeywordList::In);
389 self
390 }
391
392 pub fn where_not_in_custom(&mut self, column: &str, query: &str) -> &mut Self {
405 self.query = format!("{} WHERE {} NOT IN ({})", self.query, column, query);
406
407 self.list.push(KeywordList::NotIn);
408
409 self
410 }
411
412 pub fn or(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
425 match self.sanitize_column(column) {
426 Ok(_) => (),
427 Err(error) => panic!("{}", error)
428 }
429
430 match Self::sanitize_mark(mark) {
431 Ok(_) => (),
432 Err(error) => panic!("{}", error)
433 }
434
435 match self.sanitize_input(&value) {
436 Ok(_) => (),
437 Err(error) => panic!("{}", error)
438 }
439
440 self.query = format!("{} OR {} {} {}", self.query, column, mark, value);
441
442
443 self.list.push(KeywordList::Or);
444
445 self
446 }
447
448 pub fn set(&mut self, column: &str, value: ValueType) -> &mut Self {
466 match self.hq {
467 Some(_) => (),
468 None => self.hq = Some(Self::load_hqs())
469 }
470
471 match self.sanitize_column(column) {
472 Ok(_) => (),
473 Err(error) => panic!("{}", error)
474 }
475
476 match self.sanitize_input(&value) {
477 Ok(_) => (),
478 Err(error) => panic!("{}", error)
479 }
480
481 match self.list.last() {
482 Some(keyword) => {
483 match keyword {
484 KeywordList::Set => self.query = format!("{}, {} = {}", self.query, column, value),
485 _ => self.query = format!("{} SET {} = {}", self.query, column, value)
486 }
487 },
488 None => panic!("that's impossible to come here.")
489 }
490
491 self.list.push(KeywordList::Set);
492
493 self
494 }
495
496 pub fn and(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
509 match self.sanitize_column(column) {
510 Ok(_) => (),
511 Err(error) => panic!("{}", error)
512 }
513
514 match Self::sanitize_mark(mark) {
515 Ok(_) => (),
516 Err(error) => panic!("{}", error)
517 }
518
519 match self.sanitize_input(&value) {
520 Ok(_) => (),
521 Err(error) => panic!("{}", error)
522 }
523
524 self.query = format!("{} AND {} {} {}", self.query, column, mark, value);
525
526 self.list.push(KeywordList::And);
527
528 self
529 }
530
531 pub fn offset(&mut self, offset: i32) -> &mut Self {
544 self.query = format!("{} OFFSET {}", self.query, offset);
545
546 self.list.push(KeywordList::Offset);
547
548 self
549 }
550
551 pub fn limit(&mut self, limit: i32) -> &mut Self {
564 self.query = format!("{} LIMIT {}", self.query, limit);
565
566 self.list.push(KeywordList::Limit);
567
568 self
569 }
570
571 pub fn like(&mut self, columns: Vec<&str>, operand: &str) -> &mut Self {
587 match columns.len() {
588 0 => panic!("you cannot pass an empty vector to the columns"),
589 _ => ()
590 }
591
592 let hqs = match self.hq {
593 Some(hqs) => hqs,
594 None => {
595 let load_hqs = Self::load_hqs();
596 self.hq = Some(load_hqs);
597
598 load_hqs
599 }
600 };
601
602 match Self::sanitize_columns(&columns, hqs) {
603 Ok(_) => {
604 match self.sanitize_str(operand){
605 Ok(_) => (),
606 Err(error) => {
607 println!("That Error Occured in like method: {}", error);
608
609 self.list.push(KeywordList::Like);
610
611 return self
612 }
613 }
614
615 match self.list.last() {
616 Some(keyword) => {
617 if keyword == &KeywordList::Where || keyword == &KeywordList::In || keyword == &KeywordList::NotIn {
618 let length_of_columns = columns.len();
619
620 for (i, column) in columns.into_iter().enumerate() {
621 match length_of_columns {
622 1 => {
623 if i == 0 {
624 self.query = format!("{} AND {} LIKE '%{}%'", self.query, column, operand)
625 }
626 },
627 _ => {
628 if i == 0 {
629 self.query = format!("{} AND ({} LIKE '%{}%'", self.query, column, operand)
630 } else if i + 1 == length_of_columns {
631 self.query = format!("{} OR {} LIKE '%{}%')", self.query, column, operand)
632 } else {
633 self.query = format!("{} OR {} LIKE '%{}%'", self.query, column, operand)
634 }
635 }
636 }
637 }
638 } else {
639 for (i, column) in columns.into_iter().enumerate() {
640 if i == 0 {
641 self.query = format!("{} WHERE {} LIKE '%{}%'", self.query, column, operand);
642 } else {
643 self.query = format!("{} OR {} LIKE '%{}%'", self.query, column, operand);
644 }
645 }
646 }
647 },
648 None => panic!("Our current implementation does not support to use '.like()' later not other than WHERE, IN or NOT IN queries.")
649 }
650
651 return self
652 },
653 Err(error) => panic!("That error occured in '.like()' method: {}", error)
654 }
655 }
656
657 pub fn order_by(&mut self, column: &str, mut ordering: &str) -> &mut Self {
674 match self.sanitize_column(column) {
675 Ok(_) => (),
676 Err(error) => {
677 println!("{}", error);
678
679 self.list.push(KeywordList::OrderBy);
680
681 return self
682 }
683 }
684
685 match ordering {
686 "asc" => ordering = "ASC",
687 "desc" => ordering = "DESC",
688 "ASC" => ordering = "ASC",
689 "DESC" => ordering = "DESC",
690 &_ => panic!("Panicking in order_by method: There is no other ordering options than ASC or DESC.")
691 }
692
693 match self.list.last() {
694 Some(keyword) => match keyword {
695 KeywordList::OrderBy | KeywordList::Field => self.query = format!("{}, {} {}", self.query, column, ordering),
696 _ => self.query = format!("{} ORDER BY {} {}", self.query, column, ordering)
697 },
698 None => panic!("It's almost impossible you to come here.")
699 }
700
701 self.list.push(KeywordList::OrderBy);
702
703 self
704 }
705
706 pub fn order_random(&mut self) -> &mut Self {
723 if self.query.contains("ORDER BY") {
724 panic!("Error in order_random method: you cannot add ordering option twice on a query.");
725 }
726
727 self.query = format!("{} ORDER BY RAND()", self.query);
728 self.list.push(KeywordList::OrderBy);
729
730 self
731 }
732
733 pub fn order_by_field(&mut self, column: &str, ordering: Vec<&str>) -> &mut Self {
750 match ordering.len() {
751 0 => panic!("you cannot pass an empty vector to the ordering argument"),
752 _ => ()
753 }
754
755 match self.list.last() {
756 Some(keyword) => match keyword {
757 KeywordList::OrderBy => {
758 let mut split_the_query = self.query.split(" ORDER BY ");
759
760 self.query = format!("{} ORDER BY {}, FIELD({}", split_the_query.nth(0).unwrap(), split_the_query.nth(0).unwrap(), column);
761
762 for item in ordering {
763 self.query = format!("{}, '{}'", self.query, item)
764 }
765
766 self.query = format!("{})", self.query);
767 },
768 KeywordList::Field => {
769 self.query = format!("{}, FIELD({}", self.query, column);
770
771 for item in ordering {
772 self.query = format!("{}, '{}'", self.query, item)
773 }
774
775 self.query = format!("{})", self.query);
776 },
777 _ => {
778 let mut new_part_of_query = format!("ORDER BY FIELD({}", column);
779
780 for item in ordering {
781 new_part_of_query = format!("{}, '{}'", new_part_of_query, item)
782 }
783
784 self.query = format!("{} {})", self.query, new_part_of_query);
785 }
786 },
787 None => panic!("It's almost impossible you to come here.")
788 }
789
790 self.list.push(KeywordList::Field);
791
792 self
793 }
794
795 pub fn group_by(&mut self, column: &str) -> &mut Self {
797 self.query = format!("{} GROUP BY {}", self.query, column);
798
799 self.list.push(KeywordList::GroupBy);
800
801 self
802 }
803
804 pub fn having(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
805 match self.sanitize_column(column) {
806 Ok(_) => (),
807 Err(error) => panic!("{}", error)
808 }
809
810 match Self::sanitize_mark(mark) {
811 Ok(_) => (),
812 Err(error) => panic!("{}", error)
813 }
814
815 match self.sanitize_input(&value) {
816 Ok(_) => (),
817 Err(error) => panic!("{}", error)
818 }
819
820 self.query = format!("{} HAVING {} {} {}", self.query, column, mark, value);
821
822 self.list.push(KeywordList::Having);
823
824 self
825 }
826
827
828 pub fn union(&mut self, others: Vec<QueryBuilder<'_>>) -> &mut Self {
849 match self.list.last() {
850 Some(keyword) => {
851 match keyword {
852 KeywordList::Union | KeywordList::UnionAll => {
853 for other in others {
854 self.query = format!("{} UNION ({})", self.query, other.query)
855 }
856 },
857 _ => {
858 self.query = format!("({})", self.query);
859
860 for other in others {
861 self.query = format!("{} UNION ({})", self.query, other.query)
862 }
863 }
864 }
865 },
866 None => panic!("it's impossible to came here!")
867 }
868
869 self.list.push(KeywordList::Union);
870
871 self
872 }
873
874
875 pub fn union_all(&mut self, others: Vec<QueryBuilder<'_>>) -> &mut Self {
900 match self.list.last() {
901 Some(keyword) => {
902 match keyword {
903 KeywordList::Union | KeywordList::UnionAll => {
904 for other in others {
905 self.query = format!("{} UNION ALL ({})", self.query, other.query)
906 }
907 },
908 _ => {
909 self.query = format!("({})", self.query);
910
911 for other in others {
912 self.query = format!("{} UNION ALL ({})", self.query, other.query)
913 }
914 }
915 }
916 },
917 None => panic!("it's impossible to came here!")
918 }
919
920 self.list.push(KeywordList::UnionAll);
921
922 self
923 }
924
925 pub fn append_custom(&mut self, query: &str) -> &mut Self {
942 self.query = format!("{} {}", self.query, query);
943
944 self
945 }
946
947 pub fn append_keyword(&mut self, keyword: KeywordList) -> &mut Self {
968 self.list.push(keyword);
969
970 self
971 }
972
973 pub fn json_extract(&mut self, haystack: &str, needle: &str, _as: Option<&str>) -> &mut Self {
993 match self.list.last() {
994 Some(keyword) => {
995 match keyword {
996 KeywordList::Where => {
997 if _as.is_some() {
998 println!("Warning: You've gave _as value to some variant and used it later than 'WHERE' keyword on .json_extract() method. In that usage, that value has no effect, you should gave it none value.");
999 }
1000
1001 match self.table.as_str() == haystack {
1002 true => {
1003 let mut split_the_query = self.query.split(haystack);
1004 let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1005
1006 self.query = format!("SELECT{}{}{}", self.table, string_for_replace, split_the_query.nth(2).unwrap())
1007 },
1008 false => {
1009 let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1010
1011 self.query = self.query.replace(haystack,&string_for_replace)
1012 }
1013 }
1014 },
1015 KeywordList::And => {
1016 if _as.is_some() {
1017 println!("Warning: You've gave _as value to some variant and used it later than 'AND' keyword on .json_extract() method. In that usage, that value has no effect, you should gave it none value.");
1018 }
1019
1020 let query_to_comp = format!("AND {}", haystack);
1021
1022 match self.table.as_str() == haystack {
1023 true => {
1024 let mut split_the_query = self.query.split(&query_to_comp);
1025 let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1026
1027 self.query = format!("{}AND {}{}", split_the_query.nth(0).unwrap(), string_for_replace, split_the_query.nth(0).unwrap())
1028 },
1029 false => {
1030 match self.query.matches(&query_to_comp).count() {
1031 0 => (),
1032 1 => {
1033 let string_for_replace = format!("AND JSON_EXTRACT({}, '${}')", haystack, needle);
1034
1035 self.query = self.query.replace(&query_to_comp,&string_for_replace)
1036 }
1037 _ => {
1038 let split_the_query = self.query.split(&query_to_comp).collect::<Vec<&str>>();
1039
1040 let mut last_chunk = "".to_string();
1041 let mut new_chunk = "".to_string();
1042 let length_of_split = split_the_query.len();
1043
1044 for (index, chunk) in split_the_query.into_iter().enumerate() {
1045 if index + 1 == length_of_split {
1046 last_chunk = chunk.to_string()
1047 } else if index == 0 {
1048 new_chunk = format!("{}", chunk);
1049 } else {
1050 new_chunk = format!("{}{}{}", new_chunk, query_to_comp, chunk)
1051 }
1052 }
1053
1054 let string_for_replace = format!("AND JSON_EXTRACT({}, '${}')", haystack, needle);
1055
1056 self.query = format!("{} {} {}", new_chunk, string_for_replace, last_chunk)
1057 }
1058 }
1059 }
1060 }
1061 },
1062 KeywordList::Or => {
1063 if _as.is_some() {
1064 println!("Warning: You've gave _as value to some variant and used it later than 'OR' keyword on .json_extract() method. In that usage, that value has no effect, you should gave it none value.");
1065 }
1066
1067 let query_to_comp = format!("OR {}", haystack);
1068
1069 match self.table.as_str() == haystack {
1070 true => {
1071 let mut split_the_query = self.query.split(&query_to_comp);
1072 let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1073
1074 self.query = format!("{}OR {}{}", split_the_query.nth(0).unwrap(), string_for_replace, split_the_query.nth(0).unwrap())
1075 },
1076 false => {
1077 match self.query.matches(&query_to_comp).count() {
1078 0 => (),
1079 1 => {
1080 let string_for_replace = format!("OR JSON_EXTRACT({}, '${}')", haystack, needle);
1081
1082 self.query = self.query.replace(&query_to_comp,&string_for_replace)
1083 }
1084 _ => {
1085 let split_the_query = self.query.split(&query_to_comp).collect::<Vec<&str>>();
1086
1087 let mut last_chunk = "".to_string();
1088 let mut new_chunk = "".to_string();
1089 let length_of_split = split_the_query.len();
1090
1091 for (index, chunk) in split_the_query.into_iter().enumerate() {
1092 if index + 1 == length_of_split {
1093 last_chunk = chunk.to_string()
1094 } else if index == 0 {
1095 new_chunk = format!("{}", chunk);
1096 } else {
1097 new_chunk = format!("{}{}{}", new_chunk, query_to_comp, chunk)
1098 }
1099 }
1100
1101 let string_for_replace = format!("OR JSON_EXTRACT({}, '${}')", haystack, needle);
1102
1103 self.query = format!("{} {} {}", new_chunk, string_for_replace, last_chunk)
1104 }
1105 }
1106 }
1107 }
1108 },
1109 KeywordList::Select => {
1110 let string_for_put = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1111
1112 match _as {
1113 Some(_as) => self.query = format!("SELECT {} AS {} FROM", string_for_put, _as),
1114 None => self.query = format!("SELECT {} FROM", string_for_put),
1115 }
1116 },
1117 KeywordList::Table => {
1118 let string_for_put = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1119
1120 match _as {
1121 Some(_as) => self.query = format!("SELECT {} AS {} FROM {}", string_for_put, _as, self.table),
1122 None => self.query = format!("SELECT {} FROM {}", string_for_put, self.table),
1123 }
1124 },
1125 KeywordList::OrderBy => {
1126 if _as.is_some() {
1127 println!("Warning: You've gave _as value to some variant and used it later than 'ORDER BY' operator on .json_extract() method. In that usage, that value has no effect, you should gave it none value.");
1128 }
1129
1130 match self.query.matches(" ORDER BY ").count() {
1131 0 => (),
1132 1 => {
1133 let split_the_query = self.query.clone();
1134 let mut split_the_query = split_the_query.split(" ORDER BY ");
1135
1136 let string_for_put = format!("ORDER BY JSON_EXTRACT({}, '${}')", haystack, needle);
1137
1138 match _as {
1139 Some(_as) => self.query = format!("{} {} AS {}", split_the_query.nth(0).unwrap(), string_for_put, _as),
1140 None => self.query = format!("{} {}", split_the_query.nth(0).unwrap(), string_for_put)
1141 }
1142
1143 match split_the_query.nth(0) {
1144 Some(comparison) => {
1145 match comparison.ends_with("ASC") || comparison.ends_with("asc") {
1146 true => self.query = format!("{} ASC", self.query),
1147 false => match comparison.ends_with("DESC") || comparison.ends_with("desc") {
1148 true => self.query = format!("{} DESC", self.query),
1149 false => ()
1150 }
1151 }
1152 },
1153 None => ()
1154 }
1155 },
1156 _ => ()
1157 }
1158 },
1159 KeywordList::Count => {
1160 let mut split_the_query = self.query.split(" COUNT");
1161
1162 let string_for_put = match _as {
1163 Some(_as) => format!("JSON_EXTRACT({}, '${}') AS {}", haystack, needle, _as),
1164 None => format!("JSON_EXTRACT({}, '${}')", haystack, needle)
1165 };
1166
1167 self.query = format!("SELECT {}, COUNT{}", string_for_put, split_the_query.nth(1).unwrap())
1168 },
1169 KeywordList::JsonExtract => {
1170 let mut split_the_query = self.query.split(" FROM");
1171
1172 match _as {
1173 Some(_as) => self.query = format!("{}, JSON_EXTRACT({}, '${}') AS {} FROM", split_the_query.nth(0).unwrap(), haystack, needle, _as),
1174 None => panic!("If you want to chain .json_extract() methods, you have to give them a tag.")
1175 }
1176 }
1177 _ => ()
1178 }
1179 },
1180 None => ()
1181 }
1182
1183 self.list.push(KeywordList::JsonExtract);
1184 self
1185 }
1186
1187 pub fn json_contains(&mut self, column: &str, needle: JsonValue, path: Option<&str>) -> &mut Self {
1210 match self.list.last().unwrap() {
1211 KeywordList::Select => match path {
1212 Some(path) => match needle {
1213 JsonValue::Initial(initial) => match initial {
1214 ValueType::JsonString(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '\"{}\"', '${}') FROM", column, needle, path),
1215 ValueType::String(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1216 ValueType::Datetime(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1217 _ => self.query = format!("SELECT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1218 },
1219 _ => self.query = format!("SELECT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1220 }
1221 None => match needle {
1222 JsonValue::Initial(initial) => match initial {
1223 ValueType::JsonString(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '\"{}\"') FROM", column, needle),
1224 ValueType::String(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}') FROM", column, needle),
1225 ValueType::Datetime(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}') FROM", column, needle),
1226 _ => self.query = format!("SELECT JSON_CONTAINS({}, {}) FROM", column, needle)
1227 },
1228 _ => self.query = format!("SELECT JSON_CONTAINS({}, {}) FROM", column, needle)
1229 }
1230 },
1231 KeywordList::Where => match path {
1232 Some(path) => {
1233 let mut split_the_query = self.query.split(" WHERE ");
1234
1235 let first_half = split_the_query.nth(0);
1236
1237 match needle {
1238 JsonValue::Initial(initial) => match initial {
1239 ValueType::JsonString(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '\"{}\"', '${}')", first_half.unwrap(), column, needle, path),
1240 ValueType::String(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1241 ValueType::Datetime(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1242 _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1243 },
1244 _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1245 }
1246 },
1247 None => {
1248 let mut split_the_query = self.query.split(" WHERE ");
1249
1250 let first_half = split_the_query.nth(0);
1251
1252 match needle {
1253 JsonValue::Initial(initial) => match initial {
1254 ValueType::JsonString(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '\"{}\"')", first_half.unwrap(), column, needle),
1255 ValueType::String(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1256 ValueType::Datetime(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1257 _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1258 },
1259 _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1260 }
1261 }
1262 },
1263 KeywordList::And => match path {
1264 Some(path) => {
1265 let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1266
1267 let length_of_the_split_the_query = split_the_query.len();
1268
1269 match split_the_query.len() {
1270 0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1271 1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1272 2 => match needle {
1273 JsonValue::Initial(initial) => match initial {
1274 ValueType::JsonString(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1275 ValueType::String(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1276 ValueType::Datetime(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1277 _ => self.query = format!("{} AND JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1278 },
1279 _ => self.query = format!("{} AND JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1280 },
1281 _ => {
1282 let mut concatenated_string = String::new();
1283
1284 for (index, chunk) in split_the_query.into_iter().enumerate() {
1285 if index == 0 {
1286 concatenated_string = chunk.to_string();
1287 } else if index + 1 != length_of_the_split_the_query {
1288 concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1289 }
1290 }
1291
1292 match needle {
1293 JsonValue::Initial(initial) => match initial {
1294 ValueType::JsonString(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1295 ValueType::String(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1296 ValueType::Datetime(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1297 _ => self.query = format!("{}AND JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1298 },
1299 _ => self.query = format!("{}AND JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1300 }
1301 }
1302 }
1303 },
1304 None => {
1305 let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1306
1307 let length_of_the_split_the_query = split_the_query.len();
1308
1309 match split_the_query.len() {
1310 0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1311 1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1312 2 => match needle {
1313 JsonValue::Initial(initial) => match initial {
1314 ValueType::JsonString(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '\"{}\"')", split_the_query[0], column, needle),
1315 ValueType::String(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1316 ValueType::Datetime(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1317 _ => self.query = format!("{} AND JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1318 },
1319 _ => self.query = format!("{} AND JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1320 },
1321 _ => {
1322 let mut concatenated_string = String::new();
1323
1324 for (index, chunk) in split_the_query.into_iter().enumerate() {
1325 if index == 0 {
1326 concatenated_string = chunk.to_string();
1327 } else if index + 1 != length_of_the_split_the_query {
1328 concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1329 }
1330 }
1331
1332 match needle {
1333 JsonValue::Initial(initial) => match initial {
1334 ValueType::JsonString(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1335 ValueType::String(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1336 ValueType::Datetime(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1337 _ => self.query = format!("{}AND JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1338 },
1339 _ => self.query = format!("{}AND JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1340 }
1341 }
1342 }
1343 }
1344 },
1345 KeywordList::Or => match path {
1346 Some(path) => {
1347 let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1348
1349 let length_of_the_split_the_query = split_the_query.len();
1350
1351 match split_the_query.len() {
1352 0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1353 1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1354 2 => match needle {
1355 JsonValue::Initial(initial) => match initial {
1356 ValueType::JsonString(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1357 ValueType::String(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1358 ValueType::Datetime(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1359 _ => self.query = format!("{} OR JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1360 },
1361 _ => self.query = format!("{} OR JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1362 },
1363 _ => {
1364 let mut concatenated_string = String::new();
1365
1366 for (index, chunk) in split_the_query.into_iter().enumerate() {
1367 if index == 0 {
1368 concatenated_string = chunk.to_string();
1369 } else if index + 1 != length_of_the_split_the_query {
1370 concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1371 }
1372 }
1373
1374 match needle {
1375 JsonValue::Initial(initial) => match initial {
1376 ValueType::JsonString(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1377 ValueType::String(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1378 ValueType::Datetime(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1379 _ => self.query = format!("{}OR JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1380 },
1381 _ => self.query = format!("{}OR JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1382 }
1383 }
1384 }
1385 },
1386 None => {
1387 let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1388
1389 let length_of_the_split_the_query = split_the_query.len();
1390
1391 match split_the_query.len() {
1392 0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1393 1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1394 2 => match needle {
1395 JsonValue::Initial(initial) => match initial {
1396 ValueType::JsonString(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '\"{}\"')", split_the_query[0], column, needle),
1397 ValueType::String(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1398 ValueType::Datetime(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1399 _ => self.query = format!("{} OR JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1400 },
1401 _ => self.query = format!("{} OR JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1402 },
1403 _ => {
1404 let mut concatenated_string = String::new();
1405
1406 for (index, chunk) in split_the_query.into_iter().enumerate() {
1407 if index == 0 {
1408 concatenated_string = chunk.to_string();
1409 } else if index + 1 != length_of_the_split_the_query {
1410 concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1411 }
1412 }
1413
1414 match needle {
1415 JsonValue::Initial(initial) => match initial {
1416 ValueType::JsonString(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1417 ValueType::String(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1418 ValueType::Datetime(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1419 _ => self.query = format!("{}OR JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1420 },
1421 _ => self.query = format!("{}OR JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1422 }
1423 }
1424 }
1425 }
1426 },
1427 _ => panic!("Wrong usage of '.json_contains()' method, it should be used later than either SELECT, WHERE, AND, OR keywords.")
1428 }
1429
1430 self.list.push(KeywordList::JsonContains);
1431
1432 self
1433 }
1434
1435 pub fn not_json_contains(&mut self, column: &str, needle: JsonValue, path: Option<&str>) -> &mut Self {
1458 match self.list.last().unwrap() {
1459 KeywordList::Select => match path {
1460 Some(path) => match needle {
1461 JsonValue::Initial(initial) => match initial {
1462 ValueType::JsonString(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '\"{}\"', '${}') FROM", column, needle, path),
1463 ValueType::String(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1464 ValueType::Datetime(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1465 _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1466 },
1467 _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1468 }
1469 None => match needle {
1470 JsonValue::Initial(initial) => match initial {
1471 ValueType::JsonString(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '\"{}\"') FROM", column, needle),
1472 ValueType::String(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}') FROM", column, needle),
1473 ValueType::Datetime(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}') FROM", column, needle),
1474 _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}) FROM", column, needle)
1475 },
1476 _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}) FROM", column, needle)
1477 }
1478 },
1479 KeywordList::Where => match path {
1480 Some(path) => {
1481 let mut split_the_query = self.query.split(" WHERE ");
1482
1483 let first_half = split_the_query.nth(0);
1484
1485 match needle {
1486 JsonValue::Initial(initial) => match initial {
1487 ValueType::JsonString(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '\"{}\"', '${}')", first_half.unwrap(), column, needle, path),
1488 ValueType::String(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1489 ValueType::Datetime(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1490 _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1491 },
1492 _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1493 }
1494 },
1495 None => {
1496 let mut split_the_query = self.query.split(" WHERE ");
1497
1498 let first_half = split_the_query.nth(0);
1499
1500 match needle {
1501 JsonValue::Initial(initial) => match initial {
1502 ValueType::JsonString(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '\"{}\"')", first_half.unwrap(), column, needle),
1503 ValueType::String(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1504 ValueType::Datetime(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1505 _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1506 },
1507 _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1508 }
1509 }
1510 },
1511 KeywordList::And => match path {
1512 Some(path) => {
1513 let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1514
1515 let length_of_the_split_the_query = split_the_query.len();
1516
1517 match split_the_query.len() {
1518 0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1519 1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1520 2 => match needle {
1521 JsonValue::Initial(initial) => match initial {
1522 ValueType::JsonString(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1523 ValueType::String(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1524 ValueType::Datetime(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1525 _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1526 },
1527 _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1528 },
1529 _ => {
1530 let mut concatenated_string = String::new();
1531
1532 for (index, chunk) in split_the_query.into_iter().enumerate() {
1533 if index == 0 {
1534 concatenated_string = chunk.to_string();
1535 } else if index + 1 != length_of_the_split_the_query {
1536 concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1537 }
1538 }
1539
1540 match needle {
1541 JsonValue::Initial(initial) => match initial {
1542 ValueType::JsonString(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1543 ValueType::String(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1544 ValueType::Datetime(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1545 _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1546 },
1547 _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1548 }
1549 }
1550 }
1551 },
1552 None => {
1553 let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1554
1555 let length_of_the_split_the_query = split_the_query.len();
1556
1557 match split_the_query.len() {
1558 0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1559 1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1560 2 => match needle {
1561 JsonValue::Initial(initial) => match initial {
1562 ValueType::JsonString(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '\"{}\"')", split_the_query[0], column, needle),
1563 ValueType::String(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1564 ValueType::Datetime(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1565 _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1566 },
1567 _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1568 },
1569 _ => {
1570 let mut concatenated_string = String::new();
1571
1572 for (index, chunk) in split_the_query.into_iter().enumerate() {
1573 if index == 0 {
1574 concatenated_string = chunk.to_string();
1575 } else if index + 1 != length_of_the_split_the_query {
1576 concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1577 }
1578 }
1579
1580 match needle {
1581 JsonValue::Initial(initial) => match initial {
1582 ValueType::JsonString(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1583 ValueType::String(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1584 ValueType::Datetime(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1585 _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1586 },
1587 _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1588 }
1589 }
1590 }
1591 }
1592 },
1593 KeywordList::Or => match path {
1594 Some(path) => {
1595 let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1596
1597 let length_of_the_split_the_query = split_the_query.len();
1598
1599 match split_the_query.len() {
1600 0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1601 1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1602 2 => match needle {
1603 JsonValue::Initial(initial) => match initial {
1604 ValueType::JsonString(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1605 ValueType::String(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1606 ValueType::Datetime(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1607 _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1608 },
1609 _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1610 },
1611 _ => {
1612 let mut concatenated_string = String::new();
1613
1614 for (index, chunk) in split_the_query.into_iter().enumerate() {
1615 if index == 0 {
1616 concatenated_string = chunk.to_string();
1617 } else if index + 1 != length_of_the_split_the_query {
1618 concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1619 }
1620 }
1621
1622 match needle {
1623 JsonValue::Initial(initial) => match initial {
1624 ValueType::JsonString(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1625 ValueType::String(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1626 ValueType::Datetime(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1627 _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1628 },
1629 _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1630 }
1631 }
1632 }
1633 },
1634 None => {
1635 let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1636
1637 let length_of_the_split_the_query = split_the_query.len();
1638
1639 match split_the_query.len() {
1640 0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1641 1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1642 2 => match needle {
1643 JsonValue::Initial(initial) => match initial {
1644 ValueType::JsonString(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '\"{}\"')", split_the_query[0], column, needle),
1645 ValueType::String(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1646 ValueType::Datetime(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}')", split_the_query[0], column, needle),
1647 _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1648 },
1649 _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {})", split_the_query[0], column, needle)
1650 },
1651 _ => {
1652 let mut concatenated_string = String::new();
1653
1654 for (index, chunk) in split_the_query.into_iter().enumerate() {
1655 if index == 0 {
1656 concatenated_string = chunk.to_string();
1657 } else if index + 1 != length_of_the_split_the_query {
1658 concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1659 }
1660 }
1661
1662 match needle {
1663 JsonValue::Initial(initial) => match initial {
1664 ValueType::JsonString(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1665 ValueType::String(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1666 ValueType::Datetime(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1667 _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1668 },
1669 _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1670 }
1671 }
1672 }
1673 }
1674 },
1675 _ => panic!("Wrong usage of '.not_json_contains()' method, it should be used later than either SELECT, WHERE, AND, OR keywords.")
1676 }
1677
1678 self.list.push(KeywordList::NotJsonContains);
1679
1680 self
1681 }
1682
1683 pub fn json_array_append(&mut self, column: &str, path: Option<&str>, object: JsonValue) -> &mut Self {
1708 match self.list.last() {
1709 Some(keyword) => match keyword {
1710 KeywordList::Set => {
1711 match path {
1712 Some(path) => match object {
1713 JsonValue::Initial(initial) => match initial {
1714 ValueType::JsonString(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '\"{}\"')", self.query, column, column, path, object),
1715 ValueType::String(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
1716 ValueType::Datetime(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
1717 _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
1718 },
1719 _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
1720 }
1721 None => match object {
1722 JsonValue::Initial(initial) => match initial {
1723 ValueType::JsonString(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '\"{}\"')", self.query, column, column, object),
1724 ValueType::String(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
1725 ValueType::Datetime(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
1726 _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
1727 },
1728 _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
1729 }
1730 }
1731 },
1732 _ => {
1733 match path {
1734 Some(path) => match object {
1735 JsonValue::Initial(initial) => match initial {
1736 ValueType::JsonString(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '\"{}\"')", self.query, column, column, path, object),
1737 ValueType::String(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
1738 ValueType::Datetime(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
1739 _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
1740 },
1741 _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
1742 }
1743 None => match object {
1744 JsonValue::Initial(initial) => match initial {
1745 ValueType::JsonString(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '\"{}\"')", self.query, column, column, object),
1746 ValueType::String(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
1747 ValueType::Datetime(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
1748 _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
1749 },
1750 _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
1751 }
1752 }
1753 }
1754 },
1755 None => panic!("it's impossible to came here!")
1756 }
1757
1758 self.list.push(KeywordList::JsonArrayAppend);
1759 self
1760 }
1761
1762 pub fn json_remove(&mut self, column: &str, paths: Vec<&str>) -> &mut Self {
1780 match paths.iter().any(|path| *path == "") {
1781 true => panic!("Error: a value in the paths cannot be empty string, panicking..."),
1782 false => ()
1783 }
1784
1785 match self.list.last() {
1786 Some(keyword) => match keyword {
1787 KeywordList::Set => {
1788 self.query = format!("{}, {} = JSON_REMOVE({}", self.query, column, column);
1789
1790 for path in paths {
1791 if path.starts_with("$") {
1792 self.query = format!("{}, '${}'", self.query, path.replace("$", ""))
1793 } else {
1794 self.query = format!("{}, '${}'", self.query, path)
1795 }
1796 }
1797
1798 self.query = format!("{})", self.query)
1799 },
1800 _ => {
1801 self.query = format!("{} SET {} = JSON_REMOVE({}", self.query, column, column);
1802
1803 for path in paths {
1804 if path.starts_with("$") {
1805 self.query = format!("{}, '${}'", self.query, path.replace("$", ""))
1806 } else {
1807 self.query = format!("{}, '${}'", self.query, path)
1808 }
1809 }
1810
1811 self.query = format!("{})", self.query)
1812 }
1813 },
1814 None => panic!("it's impossible to came here!")
1815 }
1816
1817 self.list.push(KeywordList::JsonRemove);
1818 self
1819 }
1820
1821 pub fn json_set(&mut self, column: &str, path: &str, value: JsonValue) -> &mut Self {
1848 match self.list.last() {
1849 Some(keyword) => match keyword {
1850 KeywordList::Set => match value {
1851 JsonValue::Initial(initial) => match initial {
1852 ValueType::JsonString(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '\"{}\"')", self.query, column, column, path, value),
1853 ValueType::String(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
1854 ValueType::Datetime(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
1855 _ => self.query = format!("{}, {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value),
1856 },
1857 _ => self.query = format!("{}, {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value),
1858 }
1859 _ => match value {
1860 JsonValue::Initial(initial) => match initial {
1861 ValueType::JsonString(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '\"{}\"')", self.query, column, column, path, value),
1862 ValueType::String(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
1863 ValueType::Datetime(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
1864 _ => self.query = format!("{} SET {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value)
1865 },
1866 _ => self.query = format!("{} SET {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value)
1867 }
1868 },
1869 None => panic!("it's impossible to came here!")
1870 }
1871
1872 self.list.push(KeywordList::JsonSet);
1873 self
1874 }
1875
1876 pub fn json_replace(&mut self, column: &str, path: &str, value: JsonValue) -> &mut Self {
1899 match self.list.last() {
1900 Some(keyword) => match keyword {
1901 KeywordList::Set => match value {
1902 JsonValue::Initial(initial) => match initial {
1903 ValueType::JsonString(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '\"{}\"')", self.query, column, column, path, value),
1904 ValueType::String(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
1905 ValueType::Datetime(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
1906 _ => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value),
1907 },
1908 _ => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value),
1909 }
1910 _ => match value {
1911 JsonValue::Initial(initial) => match initial {
1912 ValueType::JsonString(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '\"{}\"')", self.query, column, column, path, value),
1913 ValueType::String(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
1914 ValueType::Datetime(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
1915 _ => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value)
1916 },
1917 _ => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value)
1918 }
1919 },
1920 None => panic!("it's impossible to came here!")
1921 }
1922
1923 self.list.push(KeywordList::JsonSet);
1924 self
1925 }
1926
1927 pub fn finish(&self) -> String {
1929 return format!("{};", self.query);
1930 }
1931
1932 pub fn copy(&mut self) -> Self {
1934 Self {
1935 query: self.query.clone(),
1936 table: self.table.clone(),
1937 qtype: self.qtype.clone(),
1938 list: self.list.clone(),
1939 hq: self.hq
1940 }
1941 }
1942
1943 fn load_hqs() -> [&'a str; 26] {
1944 [";", "; drop", "admin' #", "admin'/*", "; union", "or 1 = 1",
1945 "or 1 = 1#", "or 1 = 1/*", "or true = true", "or false = false", "or '1' = '1'", "or '1' = '1'#",
1946 "or '1' = '1'/*", "; sleep(", "--", "drop table", "drop schema", "select if", "union select",
1947 "union all", "exec", "master..", "masters..", "information_schema", "load_file", "alter user"]
1948 }
1949
1950 fn sanitize_column(&mut self, column: &str) -> std::result::Result<(), std::io::Error> {
1951 match self.hq {
1952 Some(hqs) => {
1953 for _hq in hqs.iter() {
1954 if &column == _hq {
1955 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
1956 }
1957 }
1958 },
1959 None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Your input is invalid."))
1960 }
1961
1962 Ok(())
1963 }
1964
1965 fn sanitize_columns(columns: &Vec<&str>, hqs: [&'a str; 26]) -> std::result::Result<(), std::io::Error> {
1967 if columns.len() == 1 && columns[0] == "" {
1968 return Ok(());
1969 };
1970
1971 for column in columns.iter() {
1972 for hq in hqs.iter() {
1973 if column == hq {
1974 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
1975 }
1976 }
1977 }
1978
1979 return Ok(())
1980 }
1981
1982 fn sanitize_inputs(inputs: &Vec<ValueType>, hqs: [&'a str; 26]) -> std::result::Result<(), std::io::Error> {
1983 for input in inputs.iter() {
1984 match input {
1985 ValueType::String(string) | ValueType::Datetime(string) => {
1986 for hq in hqs.iter() {
1987 if &string == hq {
1988 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
1989 }
1990 }
1991 },
1992 _ => continue
1993 }
1994 }
1995
1996 return Ok(())
1997 }
1998
1999 fn sanitize_input(&mut self, input: &ValueType) -> std::result::Result<(), std::io::Error> {
2000 match input {
2001 ValueType::String(string) | ValueType::Datetime(string) => {
2002 match self.hq {
2003 Some(hqs) => {
2004 for hq in hqs.iter() {
2005 if &string == hq {
2006 return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2007 }
2008 }
2009 },
2010 None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Your input is invalid."))
2011 }
2012 },
2013 _ => return Ok(())
2014 };
2015
2016 Ok(())
2017 }
2018
2019 fn sanitize_mark(input: &str) -> std::result::Result<(), std::io::Error> {
2020 return match input {
2021 "=" | "<" | ">" | "<=" | ">=" | "!=" | "<>" => Ok(()),
2022 _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=, >=, != or <>."))
2023 }
2024 }
2025
2026 fn sanitize_str(&mut self, input: &str) -> std::result::Result<(), std::io::Error> {
2027 match self.hq {
2028 Some(hqs) => {
2029 for hq in hqs.iter() {
2030 if *hq == input {
2031 return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=, >=, != or <>."))
2032 }
2033 }
2034 },
2035 None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=, >=, != or <>."))
2036 }
2037
2038 Ok(())
2039 }
2040}
2041
2042#[derive(Debug, Clone)]
2044pub struct SchemaBuilder {
2045 pub query: String,
2046 pub schema: String,
2047 pub list: Vec<KeywordList>
2048}
2049
2050impl SchemaBuilder {
2052 pub fn create(name: &str) -> std::result::Result<Self, std::io::Error> {
2053 if name.contains("!") ||
2054 name.contains("-") ||
2055 name.contains("=") ||
2056 name.contains("+") ||
2057 name.contains("%") ||
2058 name.contains("$") ||
2059 name.contains("&") ||
2060 name.contains("#") ||
2061 name.contains("[") ||
2062 name.contains("]") ||
2063 name.contains("{") ||
2064 name.contains("}") ||
2065 name.contains(":") ||
2066 name.contains(";") ||
2067 name.contains("'") ||
2068 name.contains("\"") ||
2069 name.contains(",") ||
2070 name.contains(".") {
2071 return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Schame name cannot include these characters: '!', '-', '=', '+', '%', '$', '&', '#', '[', ']', '{', '}', ':', ';', '\"', \"'\", '.', ','"))
2072 }
2073
2074 Ok(Self {
2075 query: format!("CREATE DATABASE {}", name),
2076 schema: name.to_string(),
2077 list: vec![KeywordList::Create]
2078 })
2079 }
2080
2081 pub fn use_another_schema(name: &str) -> std::result::Result<Self, std::io::Error> {
2082 if name.contains("!") ||
2083 name.contains("-") ||
2084 name.contains("=") ||
2085 name.contains("+") ||
2086 name.contains("%") ||
2087 name.contains("$") ||
2088 name.contains("&") ||
2089 name.contains("#") ||
2090 name.contains("[") ||
2091 name.contains("]") ||
2092 name.contains("{") ||
2093 name.contains("}") ||
2094 name.contains(":") ||
2095 name.contains(";") ||
2096 name.contains("'") ||
2097 name.contains("\"") ||
2098 name.contains(",") ||
2099 name.contains(".") {
2100 return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Schame name cannot include these characters: '!', '-', '=', '+', '%', '$', '&', '#', '[', ']', '{', '}', ':', ';', '\"', \"'\", '.', ','"))
2101 }
2102
2103 Ok(Self {
2104 query: format!("USE {}", name),
2105 schema: name.to_string(),
2106 list: vec![KeywordList::Use, KeywordList::Create]
2107 })
2108 }
2109
2110 pub fn if_not_exists(&mut self) -> &mut Self {
2111 match self.list[0] {
2112 KeywordList::Create => (),
2113 KeywordList::Table => (),
2114 _ => panic!("if_not_exists method cannot be used without Create or Table queries")
2115 }
2116
2117 let split_the_query = self.query.split(" DATABASE ").collect::<Vec<&str>>();
2118 self.query = format!("{} DATABASE IF NOT EXISTS {}", split_the_query[0], split_the_query[1]);
2119
2120 self.list.insert(0, KeywordList::IfNotExist);
2121 self
2122 }
2123
2124 pub fn use_schema(&mut self, name: Option<&str>) -> &mut Self {
2125 match name {
2126 Some(schema_name) => {
2127 self.query = format!("USE {}", schema_name)
2128 },
2129 None => {
2130 self.query = format!("USE {}", self.schema);
2131 }
2132 }
2133
2134 self
2135 }
2136
2137 pub fn finish(&self) -> String {
2138 return format!("{};", self.query)
2139 }
2140}
2141
2142#[derive(Debug, Clone)]
2144pub struct TableBuilder {
2145 pub query: String,
2146 pub name: String,
2147 pub schema: String,
2148 pub all: Vec<String>,
2149}
2150
2151#[derive(Debug, Clone)]
2153pub struct ForeignKey {
2154 pub first: ForeignKeyItem,
2155 pub second: ForeignKeyItem,
2156 pub on_delete: Option<ForeignKeyActions>,
2157 pub on_update: Option<ForeignKeyActions>,
2158 pub constraint: Option<String>
2159}
2160
2161#[derive(Debug, Clone)]
2163pub struct ForeignKeyItem {
2164 pub table: String,
2165 pub column: String
2166}
2167
2168impl TableBuilder {
2170 pub fn create(schema_name: &str, table_name: &str) -> Self {
2171 return Self {
2172 query: format!("CREATE TABLE {} (", table_name),
2173 schema: schema_name.to_string(),
2174 name: table_name.to_string(),
2175 all: vec![]
2176 }
2177 }
2178
2179 pub fn if_not_exists(&mut self) -> &mut Self {
2180 self.query = format!("{}IF NOT EXISTS (", self.query.replace("(", ""));
2181
2182 self
2183 }
2184
2185 pub fn add_column(&mut self, column_name: &str) -> &mut Self {
2186 if self.query.ends_with("(") {
2187 self.query = format!("{}{}", self.query, column_name)
2188 } else {
2189 self.query = format!("{}, {}", self.query, column_name)
2190 }
2191
2192 self
2193 }
2194
2195 pub fn col_type(&mut self, type_name: &str) -> &mut Self {
2196 if self.query.ends_with("(") {
2197 panic!("Cannot add type before defining a column name.")
2198 }
2199
2200 self.query = format!("{} {}", self.query, type_name);
2201
2202 self
2203 }
2204
2205 pub fn null(&mut self) -> &mut Self {
2206 self.query = format!("{} NULL", self.query);
2207
2208 self
2209 }
2210
2211 pub fn not_null(&mut self) -> &mut Self {
2212 self.query = format!("{} NOT NULL", self.query);
2213
2214 self
2215 }
2216
2217 pub fn auto_increment(&mut self) -> &mut Self {
2218 self.query = format!("{} AUTO_INCREMENT", self.query);
2219
2220 self
2221 }
2222
2223 pub fn primary_key(&mut self) -> &mut Self {
2224 if self.query.contains("PRIMARY KEY") {
2225 panic!("A table cannot have two primary keys.")
2226 }
2227
2228 self.query = format!("{} PRIMARY KEY", self.query);
2229
2230 self
2231 }
2232
2233 pub fn default(&mut self, value: ValueType) -> &mut Self {
2234 let split_the_query = self.query.clone();
2235 let split_the_query = split_the_query.split(", ").collect::<Vec<&str>>();
2236
2237 let last_query = split_the_query[split_the_query.len() - 1];
2238
2239 if last_query.contains("INT") ||
2240 last_query.contains("TINYINT") ||
2241 last_query.contains("SMALLINT") ||
2242 last_query.contains("MEDIUMINT") ||
2243 last_query.contains("BIGINT") ||
2244 last_query.contains("BIT") ||
2245 last_query.contains("SERIAL") {
2246 match value {
2247 ValueType::Int8(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2248 ValueType::Int16(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2249 ValueType::Int32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2250 ValueType::Int64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2251 ValueType::Uint8(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2252 ValueType::Uint16(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2253 ValueType::Uint32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2254 ValueType::Uint64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2255 ValueType::Usize(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2256 ValueType::Float32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2257 ValueType::Float64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2258 _ => panic!("Error: If your column has the of the types of INT, TINYINT, SMALLINT, MEDIUMINT, BIGINT, BIT or SERIAL, it has to be an i8, i16, i32, i64, i128, usize, u8, u16, u32, u64.")
2259 }
2260 }
2261
2262 if last_query.contains("BOOL") ||
2263 last_query.contains("BOOLEAN") {
2264 match value {
2265 ValueType::Boolean(boolean) => self.query = format!("{} DEFAULT {}", self.query, boolean),
2266 _ => panic!("If your column type is BOOLEAN, you have to write either true or false.")
2267 }
2268 }
2269
2270 if last_query.contains("CHAR") ||
2271 last_query.contains("VARCHAR") ||
2272 last_query.contains("TEXT") ||
2273 last_query.contains("TINYTEXT") ||
2274 last_query.contains("MEDIUMTEXT") ||
2275 last_query.contains("LONGTEXT") ||
2276 last_query.contains("BINARY") ||
2277 last_query.contains("VARBINARY") {
2278 match value {
2279 ValueType::String(ref text) => self.query = format!("{} DEFAULT '{}'", self.query, text),
2280 _ => panic!("Error: if your column type is one of the types of CHAR, VARCHAR, TEXT, TINYTEXT, MEDIUMTEXT, LONGTEXT, BINARY or VARBINARY, your value type has to be String.")
2281 }
2282 }
2283
2284 if last_query.contains("DATETIME") ||
2285 last_query.contains("TIMESTAMP") {
2286 match value {
2287 ValueType::Datetime(datetime) => self.query = format!("{} DEFAULT {}", self.query, datetime),
2288 _ => panic!("Error: if your column type is one of the types of CHAR, VARCHAR, TEXT, TINYTEXT, MEDIUMTEXT, LONGTEXT, BINARY or VARBINARY, your value type has to be String.")
2289 }
2290 }
2291
2292 self
2293 }
2294
2295 pub fn unique(&mut self) -> &mut Self {
2296 self.query = format!("{} UNIQUE", self.query);
2297
2298 self
2299 }
2300
2301 pub fn check(&mut self, condition: &str) -> &mut Self {
2302 self.query = format!("{} CHECK({})", self.query, condition);
2303
2304 self
2305 }
2306
2307 pub fn character_set(&mut self, character_set: &str) -> &mut Self {
2308 self.query = format!("{} CHARACTER SET {}", self.query, character_set);
2309
2310 self
2311 }
2312
2313 pub fn foreign_key(&mut self, opts: ForeignKey) -> &mut Self {
2314 if self.query.starts_with("ALTER TABLE") {
2315 match opts.constraint {
2316 Some(constraint) => self.query = format!("{}, ADD CONSTRAINT {} FOREIGN KEY ({})", self.query, constraint, opts.first.column),
2317 None => self.query = format!("{}, ADD FOREIGN KEY ({})", self.query, opts.first.column)
2318 }
2319
2320 } else {
2321 match opts.constraint {
2322 Some(constraint) => self.query = format!("{}, CONSTRAINT {} FOREIGN KEY ({})", self.query, constraint, opts.first.column),
2323 None => self.query = format!("{}, FOREIGN KEY ({})", self.query, opts.first.column)
2324 }
2325 }
2326
2327 self.query = format!("{} REFERENCES {}({})", self.query, opts.second.table, opts.second.column);
2328
2329 match opts.on_delete {
2330 Some(on_delete_opt) => self.query = format!("{} ON DELETE {}", self.query, on_delete_opt),
2331 None => ()
2332 }
2333
2334 match opts.on_update {
2335 Some(on_update_opt) => self.query = format!("{} ON UPDATE {}", self.query, on_update_opt),
2336 None => ()
2337 }
2338
2339 self
2340 }
2341
2342 pub fn unsigned(&mut self) -> &mut Self {
2343 self.query = format!("{} UNSIGNED", self.query);
2344
2345 self
2346 }
2347
2348 pub fn zerofill(&mut self) -> &mut Self {
2349 self.query = format!("{} ZEROFILL", self.query);
2350
2351 self
2352 }
2353
2354 pub fn enum_sql(&mut self, enum_vec: Vec<&str>) -> &mut Self {
2355 match enum_vec.len() {
2356 0 => panic!("enum_vec argument cannot be an empty vector"),
2357 _ => ()
2358 }
2359
2360 self.query = format!("{} ENUM(", self.query);
2361
2362 let length_of_enum_vec = enum_vec.len();
2363 for (index, item) in enum_vec.into_iter().enumerate() {
2364 if index + 1 == length_of_enum_vec {
2365 self.query = format!("{}'{}'", self.query, item)
2366 } else {
2367 self.query = format!("{}'{}', ", self.query, item)
2368 }
2369 }
2370
2371 self
2372 }
2373
2374 pub fn generated_always(&mut self, condition: &str) -> &mut Self {
2375 self.query = format!("{} GENERATED ALWAYS AS {}", self.query, condition);
2376
2377 self
2378 }
2379
2380 pub fn virtual_sql(&mut self) -> &mut Self {
2381 self.query = format!("{} VIRTUAL", self.query);
2382
2383 self
2384 }
2385
2386 pub fn stored(&mut self) -> &mut Self {
2387 self.query = format!("{} STORED", self.query);
2388
2389 self
2390 }
2391
2392 pub fn spatial(&mut self) -> &mut Self {
2393 self.query = format!("{} SPATIAL", self.query);
2394
2395 self
2396 }
2397
2398 pub fn generated(&mut self) -> &mut Self {
2399 self.query = format!("{} GENERATED", self.query);
2400
2401 self
2402 }
2403
2404 pub fn index(&mut self, indexes: Vec<&str>) -> &mut Self {
2405 let length_of_indexes = indexes.len();
2406
2407 match length_of_indexes {
2408 0 => panic!("There is no index here."),
2409 1 => self.query = format!("{}, INDEX({})", self.query, indexes[0]),
2410 _ => {
2411 for (i, index) in indexes.into_iter().enumerate() {
2412 if i + 1 == length_of_indexes {
2413 self.query = format!("{}{}", self.query, index);
2414
2415 continue;
2416 }
2417
2418 if i == 0 {
2419 self.query = format!("{}, INDEX ({}, ", self.query, index);
2420
2421 continue;
2422 }
2423
2424 self.query = format!("{}{}, ", self.query, index)
2425 }
2426 }
2427 }
2428
2429 self
2430 }
2431
2432 pub fn comment(&mut self, comment: &str) -> &mut Self {
2433 self.query = format!("{} COMMENT '{}'", self.query, comment);
2434
2435 self
2436 }
2437
2438 pub fn default_on_null(&mut self, value: ValueType) -> &mut Self {
2439 match value {
2440 ValueType::String(text) => self.query = format!("{} DEFAULT {} ON NULL", self.query, text),
2441 _ => self.query = format!("{} DEFAULT {} ON NULL", self.query, value),
2442 }
2443
2444 self
2445 }
2446
2447 pub fn invisible(&mut self) -> &mut Self {
2448 self.query = format!("{} INVISIBLE", self.query);
2449
2450 self
2451 }
2452
2453 pub fn custom_query(&mut self, query: &str) -> &mut Self {
2454 self.query = format!("{} {}", self.query, query);
2455
2456 self
2457 }
2458
2459 pub fn finish(&mut self) -> String {
2460 return format!("{});", self.query)
2461 }
2462}
2463
2464#[derive(Debug, Clone, PartialEq)]
2466pub enum KeywordList {
2467 Select, Update, Delete, Insert, Count, Table, Where, Or, And, Set,
2468 Finish, OrderBy, GroupBy, Having, Like, Limit, Offset, IfNotExist, Create, Use, In,
2469 NotIn, JsonExtract, JsonContains, NotJsonContains, JsonArrayAppend, JsonRemove, JsonSet, JsonReplace,
2470 Field, Union, UnionAll
2471}
2472
2473#[derive(Debug, Clone)]
2475pub enum QueryType {
2476 Select, Update, Delete, Insert, Null, Create, Count
2477}
2478
2479#[derive(Debug, Clone)]
2481pub enum ValueType {
2482 String(String), Datetime(String), Null, Boolean(bool), Int32(i32), Int16(i16), Int8(i8), Int64(i64), Int128(i128),
2483 Uint8(u8), Uint16(u16), Uint32(u32), Uint64(u64), Usize(usize), Float32(f32), Float64(f64),
2484 EpochTime(i64), JsonString(String)
2485}
2486
2487impl std::fmt::Display for ValueType {
2488 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2489 match self {
2490 ValueType::String(string) => write!(f, "'{}'", string),
2491 ValueType::JsonString(string) => write!(f, "\"{}\"", string),
2492 ValueType::Datetime(datetime) => match datetime.as_str() {
2493 "CURRENT_TIMESTAMP" | "UNIX_TIMESTAMP" | "CURRENT_DATE" | "CURRENT_TIME" | "NOW()" | "CURDATE()" | "CURTIME()" => write!(f, "{}", datetime),
2494 _ => write!(f, "'{}'", datetime)
2495 },
2496 ValueType::Null => write!(f, "NULL"),
2497 ValueType::Boolean(val) => write!(f, "{}", val),
2498 ValueType::Int8(val) => write!(f, "{}", val),
2499 ValueType::Int16(val) => write!(f, "{}", val),
2500 ValueType::Int32(val) => write!(f, "{}", val),
2501 ValueType::Int64(val) => write!(f, "{}", val),
2502 ValueType::Int128(val) => write!(f, "{}", val),
2503 ValueType::Usize(val) => write!(f, "{}", val),
2504 ValueType::Uint8(val) => write!(f, "{}", val),
2505 ValueType::Uint16(val) => write!(f, "{}", val),
2506 ValueType::Uint32(val) => write!(f, "{}", val),
2507 ValueType::Uint64(val) => write!(f, "{}", val),
2508 ValueType::Float32(val) => write!(f, "{}", val),
2509 ValueType::Float64(val) => write!(f, "{}", val),
2510 ValueType::EpochTime(val) => write!(f, "FROM_UNIXTIME({})", val),
2511 }
2512 }
2513}
2514
2515impl From<String> for ValueType { fn from(value: String) -> Self { ValueType::String(value) } }
2516impl From<bool> for ValueType { fn from(value: bool) -> Self { ValueType::Boolean(value) } }
2517impl From<i8> for ValueType { fn from(value: i8) -> Self { ValueType::Int8(value) } }
2518impl From<i16> for ValueType { fn from(value: i16) -> Self { ValueType::Int16(value) } }
2519impl From<i32> for ValueType { fn from(value: i32) -> Self { ValueType::Int32(value) } }
2520impl From<i64> for ValueType { fn from(value: i64) -> Self { ValueType::Int64(value) } }
2521impl From<i128> for ValueType { fn from(value: i128) -> Self { ValueType::Int128(value) } }
2522impl From<usize> for ValueType { fn from(value: usize) -> Self { ValueType::Usize(value) } }
2523impl From<u8> for ValueType { fn from(value: u8) -> Self { ValueType::Uint8(value) } }
2524impl From<u16> for ValueType { fn from(value: u16) -> Self { ValueType::Uint16(value) } }
2525impl From<u32> for ValueType { fn from(value: u32) -> Self { ValueType::Uint32(value) } }
2526impl From<u64> for ValueType { fn from(value: u64) -> Self { ValueType::Uint64(value) } }
2527impl From<f32> for ValueType { fn from(value: f32) -> Self { ValueType::Float32(value) } }
2528impl From<f64> for ValueType { fn from(value: f64) -> Self { ValueType::Float64(value) } }
2529
2530
2531impl Into<String> for ValueType {
2532 fn into(self) -> String {
2533 match self {
2534 ValueType::String(text) => text,
2535 ValueType::Datetime(datetime) => datetime,
2536 _ => panic!("you cannot convert a ValueType to string unless it's not a String or Datetime variant.")
2537 }
2538 }
2539}
2540
2541impl Into<bool> for ValueType {
2542 fn into(self) -> bool {
2543 match self {
2544 ValueType::Boolean(val) => val,
2545 ValueType::String(text) => match text.as_str() {
2546 "false" | "" | "\0" | "0" => false,
2547 _ => true,
2548 }
2549 ValueType::Null => false,
2550 ValueType::Int8(val) => match val == 0 {
2551 false => true,
2552 true => false
2553 },
2554 ValueType::Int16(val) => match val == 0 {
2555 false => true,
2556 true => false
2557 },
2558 ValueType::Int32(val) => match val == 0 {
2559 false => true,
2560 true => false
2561 },
2562 ValueType::Int64(val) => match val == 0 {
2563 false => true,
2564 true => false
2565 },
2566 ValueType::Int128(val) => match val == 0 {
2567 false => true,
2568 true => false
2569 },
2570 ValueType::Uint8(val) => match val == 0 {
2571 false => true,
2572 true => false
2573 },
2574 ValueType::Uint16(val) => match val == 0 {
2575 false => true,
2576 true => false
2577 },
2578 ValueType::Uint32(val) => match val == 0 {
2579 false => true,
2580 true => false
2581 },
2582 ValueType::Uint64(val) => match val == 0 {
2583 false => true,
2584 true => false
2585 },
2586 ValueType::Float32(val) => match val == 0.0 {
2587 false => true,
2588 true => false
2589 },
2590 ValueType::Float64(val) => match val == 0.0 {
2591 false => true,
2592 true => false
2593 },
2594 _ => panic!("invalid conversion")
2595 }
2596 }
2597}
2598
2599impl Into<f32> for ValueType {
2600 fn into(self) -> f32 {
2601 match self {
2602 ValueType::Float32(num) => num,
2603 ValueType::Float64(num) => num as f32,
2604 _ => panic!("invalid conversion")
2605 }
2606 }
2607}
2608
2609impl Into<f64> for ValueType {
2610 fn into(self) -> f64 {
2611 match self {
2612 ValueType::Float32(num) => num as f64,
2613 ValueType::Float64(num) => num,
2614 _ => panic!("invalid conversion")
2615 }
2616 }
2617}
2618
2619impl Into<i8> for ValueType {
2620 fn into(self) -> i8 {
2621 match self {
2622 ValueType::Int8(num) => num,
2623 ValueType::Int16(num) => match num > 128 || num < -128 {
2624 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2625 false => num as i8
2626 },
2627 ValueType::Int32(num) => match num > 128 || num < -128 {
2628 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2629 false => num as i8
2630 },
2631 ValueType::Int64(num) => match num > 128 || num < -128 {
2632 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2633 false => num as i8
2634 },
2635 ValueType::Int128(num) => match num > 128 || num < -128 {
2636 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2637 false => num as i8
2638 }
2639 ValueType::Uint8(num) => match num > 128 {
2640 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2641 false => num as i8
2642 },
2643 ValueType::Uint16(num) => match num > 128 {
2644 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2645 false => num as i8
2646 },
2647 ValueType::Uint32(num) => match num > 128 {
2648 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2649 false => num as i8
2650 },
2651 ValueType::Usize(num) => match num > 128 {
2652 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2653 false => num as i8
2654 },
2655 ValueType::Uint64(num) => match num > 128 {
2656 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2657 false => num as i8
2658 },
2659 _ => panic!("you cannot convert non numeric values into numeric ones.")
2660 }
2661 }
2662}
2663
2664impl Into<i16> for ValueType {
2665 fn into(self) -> i16 {
2666 match self {
2667 ValueType::Int8(num) => num as i16,
2668 ValueType::Int16(num) => num,
2669 ValueType::Int32(num) => match num > 32_768 || num < -32_768 {
2670 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2671 false => num as i16
2672 },
2673 ValueType::Int64(num) => match num > 32_768 || num < -32_768 {
2674 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2675 false => num as i16
2676 },
2677 ValueType::Int128(num) => match num > 32_768 || num < -32_768 {
2678 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2679 false => num as i16
2680 }
2681 ValueType::Uint8(num) => num as i16,
2682 ValueType::Uint16(num) => match num > 32_768 {
2683 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2684 false => num as i16
2685 },
2686 ValueType::Uint32(num) => match num > 32_768 {
2687 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2688 false => num as i16
2689 },
2690 ValueType::Usize(num) => match num > 32_768 {
2691 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2692 false => num as i16
2693 },
2694 ValueType::Uint64(num) => match num > 32_768 {
2695 true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2696 false => num as i16
2697 },
2698 _ => panic!("you cannot convert non numeric values into numeric ones.")
2699 }
2700 }
2701}
2702
2703impl Into<i32> for ValueType {
2704 fn into(self) -> i32 {
2705 match self {
2706 ValueType::Int8(num) => num as i32,
2707 ValueType::Int16(num) => num as i32,
2708 ValueType::Int32(num) => num,
2709 ValueType::Int64(num) => match num > 2_147_483_647 || num < -2_147_483_647 {
2710 true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2711 false => num as i32
2712 },
2713 ValueType::Int128(num) => match num > 2_147_483_647 || num < -2_147_483_647 {
2714 true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2715 false => num as i32
2716 }
2717 ValueType::Uint8(num) => num as i32,
2718 ValueType::Uint16(num) => num as i32,
2719 ValueType::Uint32(num) => match num > 2_147_483_647 {
2720 true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2721 false => num as i32
2722 },
2723 ValueType::Usize(num) => match num > 2_147_483_647 {
2724 true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2725 false => num as i32
2726 },
2727 ValueType::Uint64(num) => match num > 2_147_483_647 {
2728 true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2729 false => num as i32
2730 }
2731 _ => panic!("you cannot convert non numeric values into numeric ones.")
2732 }
2733 }
2734}
2735
2736impl Into<i64> for ValueType {
2737 fn into(self) -> i64 {
2738 match self {
2739 ValueType::EpochTime(epoch) => epoch as i64,
2740 ValueType::Int8(num) => num as i64,
2741 ValueType::Int16(num) => num as i64,
2742 ValueType::Int32(num) => num as i64,
2743 ValueType::Int64(num) => num,
2744 ValueType::Usize(num) => num as i64,
2745 ValueType::Uint8(num) => num as i64,
2746 ValueType::Uint16(num) => num as i64,
2747 ValueType::Uint32(num) => num as i64,
2748 ValueType::Uint64(num) => num as i64,
2749 _ => panic!("you cannot convert non numeric values into numeric ones.")
2750 }
2751 }
2752}
2753
2754impl Into<u8> for ValueType {
2755 fn into(self) -> u8 {
2756 match self {
2757 ValueType::Uint8(num) => num,
2758 ValueType::Uint16(num) => match num > 255 {
2759 true => panic!("you cannot convert u16's if it's value is bigger than capacity of 8 bit values"),
2760 false => num as u8
2761 },
2762 ValueType::Uint32(num) => match num > 255 {
2763 true => panic!("you cannot convert u32's if it's value is bigger than capacity of 8 bit values"),
2764 false => num as u8
2765 },
2766 ValueType::Uint64(num) => match num > 255 {
2767 true => panic!("you cannot convert u64's if it's value is bigger than capacity of 8 bit values"),
2768 false => num as u8
2769 },
2770 ValueType::Usize(num) => match num > 255 {
2771 true => panic!("you cannot convert usizes if it's value is bigger than capacity of 8 bit values"),
2772 false => num as u8
2773 },
2774 ValueType::Int8(num) => match num < 0 {
2775 true => panic!("you cannot convert i8's if it's value is lower than 0"),
2776 false => num as u8
2777 },
2778 ValueType::Int16(num) => match num < 0 || num > 255 {
2779 true => panic!("you cannot convert i16's if it's value is lower than 0 or has a value which is bigger than capacity of 8 bit values."),
2780 false => num as u8
2781 },
2782 ValueType::Int32(num) => match num < 0 || num > 255 {
2783 true => panic!("you cannot convert i32's if it's value is lower than 0 or has a value which is bigger than capacity of 8 bit values."),
2784 false => num as u8
2785 },
2786 ValueType::Int64(num) => match num < 0 || num > 255 {
2787 true => panic!("you cannot convert 64's if it's value is lower than 0 or has a value which is bigger than capacity of 8 bit values."),
2788 false => num as u8
2789 },
2790 ValueType::Int128(num) => match num < 0 || num > 255 {
2791 true => panic!("you cannot convert i128's if it's value is lower than 0 or has a value which is bigger than capacity of 8 bit values."),
2792 false => num as u8
2793 }
2794 _ => panic!("you cannot convert non numeric values into numeric ones.")
2795 }
2796 }
2797}
2798
2799impl Into<u16> for ValueType {
2800 fn into(self) -> u16 {
2801 match self {
2802 ValueType::Uint8(num) => num as u16,
2803 ValueType::Uint16(num) => num,
2804 ValueType::Uint32(num) => match num > 65_535 {
2805 true => panic!("you cannot convert u32's if it's value is bigger than capacity of 32 bit values"),
2806 false => num as u16
2807 },
2808 ValueType::Uint64(num) => match num > 65_535 {
2809 true => panic!("you cannot convert u64's if it's value is bigger than capacity of 32 bit values"),
2810 false => num as u16
2811 },
2812 ValueType::Usize(num) => match num > 65_535 {
2813 true => panic!("you cannot convert usizes if it's value is bigger than capacity of 32 bit values"),
2814 false => num as u16
2815 },
2816 ValueType::Int8(num) => match num < 0 {
2817 true => panic!("you cannot convert i8's if it's value is lower than 0"),
2818 false => num as u16
2819 },
2820 ValueType::Int16(num) => match num < 0 {
2821 true => panic!("you cannot convert i16's if it's value is lower than 0"),
2822 false => num as u16
2823 },
2824 ValueType::Int32(num) => match num < 0 || num > 65_535 {
2825 true => panic!("you cannot convert i32's if it's value is lower than 0 or has a value which is bigger than capacity of 16 bit values."),
2826 false => num as u16
2827 },
2828 ValueType::Int64(num) => match num < 0 || num > 65_535 {
2829 true => panic!("you cannot convert i64's if it's value is lower than 0 or has a value which is bigger than capacity of 16 bit values."),
2830 false => num as u16
2831 },
2832 ValueType::Int128(num) => match num < 0 || num > 65_535 {
2833 true => panic!("you cannot convert i128's if it's value is lower than 0 or has a value which is bigger than capacity of 16 bit values."),
2834 false => num as u16
2835 }
2836 _ => panic!("you cannot convert non numeric values into numeric ones.")
2837 }
2838 }
2839}
2840
2841impl Into<u32> for ValueType {
2842 fn into(self) -> u32 {
2843 match self {
2844 ValueType::Uint8(num) => num as u32,
2845 ValueType::Uint16(num) => num as u32,
2846 ValueType::Uint32(num) => num,
2847 ValueType::Uint64(num) => match num > 4_294_967_295 {
2848 true => panic!("you cannot convert u64's if it's value is bigger than capacity of 32 bit values"),
2849 false => num as u32
2850 },
2851 ValueType::Usize(num) => match num > 4_294_967_295 {
2852 true => panic!("you cannot convert usizes if it's value is bigger than capacity of 32 bit values"),
2853 false => num as u32
2854 },
2855 ValueType::Int8(num) => match num < 0 {
2856 true => panic!("you cannot convert i8's if it's value is lower than 0"),
2857 false => num as u32
2858 },
2859 ValueType::Int16(num) => match num < 0 {
2860 true => panic!("you cannot convert i16's if it's value is lower than 0"),
2861 false => num as u32
2862 },
2863 ValueType::Int32(num) => match num < 0 {
2864 true => panic!("you cannot convert i32's if it's value is lower than 0"),
2865 false => num as u32
2866 },
2867 ValueType::Int64(num) => match num < 0 || num > 4_294_967_295 {
2868 true => panic!("you cannot convert i64's if it's value is lower than 0 or has a value which is bigger than capacity of 32 bit values."),
2869 false => num as u32
2870 },
2871 ValueType::Int128(num) => match num < 0 || num > 4_294_967_295 {
2872 true => panic!("you cannot convert i128's if it's value is lower than 0 or has a value which is bigger than capacity of 32 bit values."),
2873 false => num as u32
2874 }
2875 _ => panic!("you cannot convert non numeric values into numeric ones.")
2876 }
2877 }
2878}
2879
2880impl Into<u64> for ValueType {
2881 fn into(self) -> u64 {
2882 match self {
2883 ValueType::Usize(num) => num as u64,
2884 ValueType::Uint8(num) => num as u64,
2885 ValueType::Uint16(num) => num as u64,
2886 ValueType::Uint32(num) => num as u64,
2887 ValueType::Uint64(num) => num,
2888 ValueType::Int8(num) => match num < 0 {
2889 true => panic!("you cannot turn a negative value into u64"),
2890 false => num as u64
2891 },
2892 ValueType::Int16(num) => match num < 0 {
2893 true => panic!("you cannot turn a negative value into u64"),
2894 false => num as u64
2895 },
2896 ValueType::Int32(num) => match num < 0 {
2897 true => panic!("you cannot turn a negative value into u64"),
2898 false => num as u64
2899 },
2900 ValueType::Int64(num) => match num < 0 {
2901 true => panic!("you cannot turn a negative value into u64"),
2902 false => num as u64
2903 },
2904 ValueType::Int128(num) => match num < 0 {
2905 true => panic!("you cannot turn a negative value into u64"),
2906 false => num as u64
2907 },
2908 _ => panic!("you cannot convert non numeric values into numeric ones.")
2909 }
2910 }
2911}
2912
2913impl Into<usize> for ValueType {
2914 fn into(self) -> usize {
2915 match self {
2916 ValueType::Int8(num) => match num < 0 {
2917 true => panic!("you cannot convert negative numbers to usize"),
2918 false => num as usize
2919 },
2920 ValueType::Int16(num) => match num < 0 {
2921 true => panic!("you cannot convert negative numbers to usize"),
2922 false => num as usize
2923 },
2924 ValueType::Int32(num) => match num < 0 {
2925 true => panic!("you cannot convert negative numbers to usize"),
2926 false => num as usize
2927 },
2928 ValueType::Int64(num) => match num < 0 {
2929 true => panic!("you cannot convert negative numbers to usize"),
2930 false => num as usize
2931 },
2932 ValueType::Int128(num) => match num < 0 {
2933 true => panic!("you cannot convert negative numbers to usize"),
2934 false => num as usize
2935 },
2936 ValueType::Usize(num) => num,
2937 ValueType::Uint8(num) => num as usize,
2938 ValueType::Uint16(num) => num as usize,
2939 ValueType::Uint32(num) => num as usize,
2940 ValueType::Uint64(num) => num as usize,
2941 _ => panic!("you cannot convert non numeric values into numeric ones.")
2942 }
2943 }
2944}
2945
2946#[derive(Debug, Clone)]
2949pub enum JsonValue<'a> {
2950 Array(&'a Vec<ValueType>),
2954
2955 Object(&'a Vec<(&'a str, &'a ValueType)>),
2959
2960 ObjectArray(&'a Vec<Vec<(&'a str, &'a ValueType)>>),
2964
2965 Initial(&'a ValueType),
2967
2968 MysqlJsonObject(&'a Vec<(&'a str, &'a ValueType)>)
2970}
2971
2972impl <'a>std::fmt::Display for JsonValue<'a> {
2973 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2974 match self {
2975 JsonValue::Array(values) => {
2976 let mut json_str = "[".to_string();
2977
2978 for (index, value) in values.iter().enumerate() {
2979 if index == 0 {
2980 json_str = format!("{}{}", json_str, value)
2981 } else {
2982 json_str = format!("{}, {}", json_str, value)
2983 }
2984 }
2985
2986 json_str = format!("{}]", json_str);
2987
2988 write!(f, "{}", json_str)
2989 },
2990 JsonValue::Object(props) => {
2991 let mut json_str = "{".to_string();
2992
2993 for (index, value) in props.iter().enumerate() {
2994 if index == 0 {
2995 json_str = format!("{}\"{}\": {}", json_str, value.0, value.1)
2996 } else {
2997 json_str = format!("{}, \"{}\": {}", json_str, value.0, value.1)
2998 }
2999 }
3000
3001 json_str = format!("{}}}", json_str);
3002
3003 write!(f, "{}", json_str)
3004 },
3005 JsonValue::MysqlJsonObject(props) => {
3006 let mut json_str = "JSON_OBJECT(".to_string();
3007
3008 for (index, value) in props.iter().enumerate() {
3009 if index == 0 {
3010 json_str = format!("{}'{}', {}", json_str, value.0, value.1)
3011 } else {
3012 json_str = format!("{}, '{}', {}", json_str, value.0, value.1)
3013 }
3014 }
3015
3016 json_str = format!("{})", json_str);
3017
3018 write!(f, "{}", json_str)
3019 },
3020 JsonValue::ObjectArray(array) => {
3021 let mut json_str = "[".to_string();
3022
3023 for (index1, object) in array.into_iter().enumerate() {
3024 let mut object_str = "{".to_string();
3025
3026 for (index2, property) in object.into_iter().enumerate() {
3027 if index2 == 0 {
3028 object_str = format!("{}\"{}\": {}", object_str, property.0, property.1)
3029 } else {
3030 object_str = format!("{}, \"{}\": {}", object_str, property.0, property.1)
3031 }
3032 }
3033
3034 object_str = format!("{}}}", object_str);
3035
3036 if index1 == 0 {
3037 json_str = format!("{}{}", json_str, object_str)
3038 } else {
3039 json_str = format!("{}, {}", json_str, object_str)
3040 }
3041 }
3042
3043 write!(f, "{}]", json_str)
3044 },
3045 JsonValue::Initial(value) => write!(f, "{}", value.to_string())
3046 }
3047 }
3048}
3049
3050#[derive(Debug, Clone)]
3052pub enum ForeignKeyActions {
3053 Cascade, Restrict, SetNull, NoAction, SetDefault
3054}
3055
3056impl std::fmt::Display for ForeignKeyActions {
3057 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3058 match self {
3059 &ForeignKeyActions::Cascade => write!(f, "CASCADE"),
3060 &ForeignKeyActions::NoAction => write!(f, "NO ACTION"),
3061 &ForeignKeyActions::Restrict => write!(f, "RESTRICT"),
3062 &ForeignKeyActions::SetNull => write!(f, "SET NULL"),
3063 &ForeignKeyActions::SetDefault => write!(f, "SET DEFAULT")
3064 }
3065 }
3066}
3067
3068#[cfg(test)]
3069mod test {
3070 use super::*;
3071
3072 #[test]
3073 pub fn test_schema_query_declarative(){
3074 let schema = SchemaBuilder::create("blog_website").unwrap().if_not_exists().finish();
3075
3076 assert_eq!("CREATE DATABASE IF NOT EXISTS blog_website;", schema);
3077 }
3078
3079 #[test]
3080 pub fn test_schema_query_imperative(){
3081 let mut schema = SchemaBuilder::create("blog_website").unwrap();
3082 schema.if_not_exists();
3083 let schema_query = schema.finish();
3084
3085 assert_eq!("CREATE DATABASE IF NOT EXISTS blog_website;", schema_query);
3086 }
3087
3088 #[test]
3089 pub fn test_use_another_schema(){
3090 let schema = SchemaBuilder::use_another_schema("chat_website").unwrap().finish();
3091
3092 assert_eq!("USE chat_website;", schema);
3093 }
3094
3095 #[test]
3096 pub fn test_insert_query(){
3097 let columns = vec!["title", "author", "description"];
3098 let values = vec![ValueType::String("What's Up?".to_string()), ValueType::String("John Doe".to_string()), ValueType::String("Lorem ipsum dolor sit amet, consectetur adipiscing elit.".to_string())];
3099
3100 let insert_query = QueryBuilder::insert(columns, values).unwrap().table("blogs").finish();
3101
3102 println!("{}", insert_query);
3103 assert_eq!("INSERT INTO blogs (title, author, description) VALUES ('What's Up?', 'John Doe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');".to_string(),
3104 insert_query);
3105 }
3106
3107 #[test]
3108 pub fn test_update_query(){
3109 let update_query = QueryBuilder::update().unwrap().table("blogs").set("title", ValueType::String("Hello Rust!".to_string())).set("author", ValueType::String("Necdet".to_string())).finish();
3110
3111 assert_eq!("UPDATE blogs SET title = 'Hello Rust!', author = 'Necdet';", update_query);
3112 }
3113
3114 #[test]
3115 pub fn test_delete_query(){
3116 let delete_query = QueryBuilder::delete().unwrap().table("blogs").where_("id", "=", ValueType::String("1".to_string())).finish();
3117
3118 assert_eq!("DELETE FROM blogs WHERE id = '1';", delete_query);
3119 }
3120
3121 #[test]
3122 pub fn test_select_query_declarative(){
3123 let mut select = QueryBuilder::select(["id", "title", "description", "point"].to_vec()).unwrap();
3124
3125 let select_query = select.table("blogs")
3126 .where_("id", "=", ValueType::Int32(10))
3127 .and("point", ">", ValueType::Int8(90))
3128 .or("id", "=", ValueType::Int64(20))
3129 .finish();
3130
3131 assert_eq!("SELECT id, title, description, point FROM blogs WHERE id = 10 AND point > 90 OR id = 20;", select_query)
3132 }
3133
3134 #[test]
3135 pub fn test_select_query_imperative(){
3136 let mut select = QueryBuilder::select(["*"].to_vec()).unwrap();
3137
3138 let select_query = select.table("blogs");
3139 select_query.where_("id", "=", ValueType::Uint8(5));
3140 select_query.or("id", "=", ValueType::Usize(25));
3141
3142 let finish_the_select_query = select_query.finish();
3143
3144 assert_eq!("SELECT * FROM blogs WHERE id = 5 OR id = 25;", finish_the_select_query);
3145 }
3146
3147 #[test]
3148 pub fn test_create_table() {
3149 let mut table_builder_2 = TableBuilder::create("blabla", "projects");
3150 let table_builder_2 = table_builder_2.if_not_exists();
3151
3152 table_builder_2.add_column("id").col_type("INT").primary_key().auto_increment();
3153 table_builder_2.add_column("name").col_type("VARCHAR(40)").not_null();
3154 table_builder_2.add_column("owner_id").col_type("INT").not_null();
3155
3156 let opts = ForeignKey {
3158 first: ForeignKeyItem { table: "".to_string(), column: "owner_id".to_string() },
3159 second: ForeignKeyItem { table: "users".to_string(), column: "id".to_string() },
3160 constraint: None,
3161 on_delete: Some(ForeignKeyActions::Cascade),
3162 on_update: None
3163 };
3164
3165 table_builder_2.foreign_key(opts);
3166
3167 let table_builder_2 = table_builder_2.finish();
3168
3169 let raw_query = "CREATE TABLE projects IF NOT EXISTS (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(40) NOT NULL, owner_id INT NOT NULL, FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE);".to_string();
3170
3171 assert_eq!(raw_query, table_builder_2);
3172 }
3173
3174 #[test]
3175 pub fn test_time_value_type(){
3176 let columns = ["name", "password", "last_login"].to_vec();
3177 let values = [ValueType::String("necoo33".to_string()), ValueType::String("123456".to_string()), ValueType::Datetime("CURRENT_TIMESTAMP".to_string())].to_vec();
3178
3179 let time_insert_test = QueryBuilder::insert(columns, values).unwrap().table("users").finish();
3180
3181 assert_eq!(time_insert_test, "INSERT INTO users (name, password, last_login) VALUES ('necoo33', '123456', CURRENT_TIMESTAMP);");
3182
3183 let time_update_test = QueryBuilder::update().unwrap().table("users").set("last_login", ValueType::Datetime("CURRENT_TIMESTAMP".to_string())).where_("name", "=", ValueType::String("necoo33".to_string())).finish();
3184
3185 assert_eq!(time_update_test, "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE name = 'necoo33';")
3186 }
3187
3188 #[test]
3189 pub fn test_unix_epoch_times(){
3190 let columns = ["name", "password", "last_login"].to_vec();
3191 let values = [ValueType::String("necoo33".to_string()), ValueType::String("123456".to_string()), ValueType::EpochTime(134523452)].to_vec();
3192
3193 let time_insert_with_unix_epoch_times_test = QueryBuilder::insert(columns, values).unwrap().table("users").finish();
3194 assert_eq!(time_insert_with_unix_epoch_times_test, "INSERT INTO users (name, password, last_login) VALUES ('necoo33', '123456', FROM_UNIXTIME(134523452));");
3195
3196 let time_update_with_unix_epoch_times_test = QueryBuilder::update().unwrap().table("users").set("last_login", ValueType::EpochTime(3456436)).where_("name", "=", ValueType::String("necoo33".to_string())).finish();
3197
3198 assert_eq!(time_update_with_unix_epoch_times_test, "UPDATE users SET last_login = FROM_UNIXTIME(3456436) WHERE name = 'necoo33';");
3199
3200 let columns = ["name", "password", "last_login", "created_at"].to_vec();
3201
3202 let unix_epoch_times_test_3 = QueryBuilder::select(columns).unwrap().table("users").where_("created_at", ">", ValueType::EpochTime(3234534)).or("last_login", ">=", ValueType::EpochTime(2134432)).offset(0).limit(20).finish();
3203
3204 assert_eq!(unix_epoch_times_test_3, "SELECT name, password, last_login, created_at FROM users WHERE created_at > FROM_UNIXTIME(3234534) OR last_login >= FROM_UNIXTIME(2134432) OFFSET 0 LIMIT 20;")
3205 }
3206
3207 #[test]
3208 pub fn test_where_ins(){
3209 let columns = ["name", "age", "id", "last_login"].to_vec();
3210
3211 let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3212
3213 let test_where_in = QueryBuilder::select(columns).unwrap().table("users").where_in("id", &ids).finish();
3214
3215 assert_eq!(test_where_in, "SELECT name, age, id, last_login FROM users WHERE id IN (1, 12, 8);");
3216
3217 let columns = ["name", "age", "id", "last_login"].to_vec();
3218
3219 let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int32(8)].to_vec();
3220
3221 let test_where_not_in = QueryBuilder::select(columns).unwrap().table("users").where_not_in("id", &ids).finish();
3222
3223 assert_eq!(test_where_not_in, "SELECT name, age, id, last_login FROM users WHERE id NOT IN (1, 12, 8);");
3224
3225 let columns = ["name", "age", "id", "last_login"].to_vec();
3226
3227 let test_where_in_custom = QueryBuilder::select(columns).unwrap().table("users").where_in_custom("id", "1, 12, 8").finish();
3228
3229 assert_eq!(test_where_in_custom, "SELECT name, age, id, last_login FROM users WHERE id IN (1, 12, 8);");
3230
3231 let columns = ["name", "age", "id", "last_login"].to_vec();
3232
3233 let test_where_not_in_custom = QueryBuilder::select(columns).unwrap().table("users").where_not_in_custom("id", "1, 12, 8").finish();
3234
3235 assert_eq!(test_where_not_in_custom, "SELECT name, age, id, last_login FROM users WHERE id NOT IN (1, 12, 8);")
3236 }
3237
3238 #[test]
3239 pub fn test_count() {
3240 let count_of_users = QueryBuilder::count("*", None).table("users").where_("age", ">", ValueType::Int32(25)).finish();
3241
3242 assert_eq!(count_of_users, "SELECT COUNT(*) FROM users WHERE age > 25;".to_string());
3243
3244 let count_of_users_as_length = QueryBuilder::count("*", Some("length")).table("users").finish();
3245
3246 assert_eq!(count_of_users_as_length, "SELECT COUNT(*) AS length FROM users;".to_string());
3247 }
3248
3249 #[test]
3250 pub fn test_json_extract(){
3251 let select_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").finish();
3254
3255 assert_eq!(select_query_1, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students;".to_string());
3256
3257 let select_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").where_("successfull", "=", ValueType::Int8(1)).finish();
3258
3259 assert_eq!(select_query_2, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students WHERE successfull = 1;".to_string());
3260
3261 let select_query_3 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").where_("points", ">", ValueType::Int32(85)).json_extract("points", ".name", None).finish();
3262
3263 assert_eq!(select_query_3, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students WHERE JSON_EXTRACT(points, '$.name') > 85;".to_string());
3264
3265 let with_where = QueryBuilder::delete().unwrap().table("users").where_("id", ">", ValueType::Int32(200)).json_extract("id", ".user_id", None).finish();
3268
3269 assert_eq!(with_where, "DELETE FROM users WHERE JSON_EXTRACT(id, '$.user_id') > 200;".to_string());
3270
3271 let fields = ["name", "age"].to_vec();
3274
3275 let with_table = QueryBuilder::select(fields).unwrap().table("users").json_extract("id", ".user_id", None).finish();
3276
3277 assert_eq!(with_table, "SELECT JSON_EXTRACT(id, '$.user_id') FROM users;".to_string());
3278
3279 let fields = ["name", "age"].to_vec();
3282
3283 let with_and_1 = QueryBuilder::select(fields).unwrap().table("height").where_("weight", ">", ValueType::Int32(60)).and("height", ">", ValueType::Float64(1.70)).json_extract("height", ".student_height", None).finish();
3284
3285 assert_eq!(with_and_1, "SELECT name, age FROM height WHERE weight > 60 AND JSON_EXTRACT(height, '$.student_height') > 1.7;".to_string());
3286
3287 let with_and_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("students").where_("weight", ">", ValueType::Int32(60)).and("height", ">", ValueType::Float64(1.70)).json_extract("height", ".student_height", None).finish();
3288
3289 assert_eq!(with_and_2, "SELECT * FROM students WHERE weight > 60 AND JSON_EXTRACT(height, '$.student_height') > 1.7;".to_string());
3290
3291 let fields = ["name", "age"].to_vec();
3294
3295 let with_or_1 = QueryBuilder::select(fields).unwrap().table("height").where_("weight", ">", ValueType::Int32(60)).or("height", ">", ValueType::Float64(1.71)).json_extract("height", ".student_height", None).finish();
3296
3297 assert_eq!(with_or_1, "SELECT name, age FROM height WHERE weight > 60 OR JSON_EXTRACT(height, '$.student_height') > 1.71;".to_string());
3298
3299 let with_or_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("students").where_("weight", ">", ValueType::Int32(60)).or("height", ">", ValueType::Float64(1.71)).json_extract("height", ".student_height", None).finish();
3300
3301 assert_eq!(with_or_2, "SELECT * FROM students WHERE weight > 60 OR JSON_EXTRACT(height, '$.student_height') > 1.71;".to_string());
3302
3303 let count_query_1 = QueryBuilder::count("*", None).json_extract("age", ".student_age", Some("value")).table("students").group_by("points").having("points", ">", ValueType::Int32(75)).finish();
3306
3307 assert_eq!(count_query_1, "SELECT JSON_EXTRACT(age, '$.student_age') AS value, COUNT(*) FROM students GROUP BY points HAVING points > 75;".to_string());
3308
3309 let fields = ["title", "desc", "created_at", "updated_at", "keywords", "pics", "likes"].to_vec();
3312
3313 let order_by_query_1 = QueryBuilder::select(fields).unwrap().table("contents").where_("published", "=", ValueType::Int32(1)).order_by("likes", "ASC").json_extract("likes", ".name", None).finish();
3314
3315 assert_eq!(order_by_query_1, "SELECT title, desc, created_at, updated_at, keywords, pics, likes FROM contents WHERE published = 1 ORDER BY JSON_EXTRACT(likes, '$.name') ASC;".to_string());
3316
3317 let json_extract_chaining = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("articles", "[0]", Some("blog1")).json_extract("articles", "[1]", Some("blog2")).json_extract("articles", "[2]", Some("blog3")).table("users").where_("published", "=", ValueType::Int32(1)).finish();
3320
3321 assert_eq!(json_extract_chaining, "SELECT JSON_EXTRACT(articles, '$[0]') AS blog1, JSON_EXTRACT(articles, '$[1]') AS blog2, JSON_EXTRACT(articles, '$[2]') AS blog3 FROM users WHERE published = 1;".to_string());
3322 }
3323
3324 #[test]
3325 pub fn test_json_contains(){
3326 let ins = [ValueType::Int32(1), ValueType::Int32(5), ValueType::Int64(11)].to_vec();
3329 let select_query = QueryBuilder::select(["*"].to_vec()).unwrap().json_contains("pic", JsonValue::Initial(&ValueType::String("\"/files/hello.jpg\"".to_string())), Some(".path")).table("users").where_in("id", &ins).finish();
3330
3331 assert_eq!(select_query, "SELECT JSON_CONTAINS(pic, '\"/files/hello.jpg\"', '$.path') FROM users WHERE id IN (1, 5, 11);".to_string());
3332
3333 let where_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("pic", "=", ValueType::String("".to_string())).json_contains("pic", JsonValue::Initial(&ValueType::String("\"blablabla.jpg\"".to_string())), Some(".name")).finish();
3336
3337 assert_eq!(where_query, "SELECT * FROM users WHERE JSON_CONTAINS(pic, '\"blablabla.jpg\"', '$.name');".to_string());
3338
3339 let and_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).and("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3340
3341 assert_eq!(and_query_1, "SELECT * FROM users WHERE age > 15 AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3342
3343 let and_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).and("class", "=", ValueType::String("5/c".to_string())).and("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3344
3345 assert_eq!(and_query_2, "SELECT * FROM users WHERE age > 15 AND class = '5/c' AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3346
3347 let and_query_3 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).and("class", "=", ValueType::String("5/c".to_string())).and("surname", "=", ValueType::String("etiman".to_string())).and("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3348
3349 assert_eq!(and_query_3, "SELECT * FROM users WHERE age > 15 AND class = '5/c' AND surname = 'etiman' AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3350
3351 let and_query_4 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).and("sdfgsdfg", "=", ValueType::String("".to_string())).json_contains("parents", JsonValue::Initial(&ValueType::Int32(50)), Some(".age")).and("surname", "=", ValueType::String("etiman".to_string())).and("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float32(80.11)), Some(".average_point")).finish();
3352
3353 assert_eq!(and_query_4, "SELECT * FROM users WHERE age > 15 AND JSON_CONTAINS(parents, 50, '$.age') AND surname = 'etiman' AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3354
3355 let and_query_5 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).and("sdfgsdfg", "=", ValueType::String("".to_string())).json_contains("parents", JsonValue::Initial(&ValueType::Int32(50)), Some(".age")).and("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3356
3357 assert_eq!(and_query_5, "SELECT * FROM users WHERE age > 15 AND JSON_CONTAINS(parents, 50, '$.age') AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3358
3359 let or_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).or("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float32(80.11)), Some(".average_point")).finish();
3360
3361 assert_eq!(or_query_1, "SELECT * FROM users WHERE age > 15 OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3362
3363 let or_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).or("class", "=", ValueType::String("5/c".to_string())).or("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3364
3365 assert_eq!(or_query_2, "SELECT * FROM users WHERE age > 15 OR class = '5/c' OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3366
3367 let or_query_3 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).or("class", "=", ValueType::String("5/c".to_string())).or("surname", "=", ValueType::String("etiman".to_string())).or("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3368
3369 assert_eq!(or_query_3, "SELECT * FROM users WHERE age > 15 OR class = '5/c' OR surname = 'etiman' OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3370
3371 let or_query_4 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).or("sdfgsdfg", "=", ValueType::String("".to_string())).json_contains("parents", JsonValue::Initial(&ValueType::Int32(50)), Some(".age")).or("surname", "=", ValueType::String("etiman".to_string())).or("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float64(80.11)), Some(".average_point")).finish();
3372
3373 assert_eq!(or_query_4, "SELECT * FROM users WHERE age > 15 OR JSON_CONTAINS(parents, 50, '$.age') OR surname = 'etiman' OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3374
3375 let or_query_5 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("age", ">", ValueType::Int32(15)).or("sdfgsdfg", "=", ValueType::String("".to_string())).json_contains("parents", JsonValue::Initial(&ValueType::Int64(50)), Some(".age")).or("asdfasdf", ">", ValueType::String("".to_string())).json_contains("graduation_stats", JsonValue::Initial(&ValueType::Float32(80.11)), Some(".average_point")).finish();
3376
3377 assert_eq!(or_query_5, "SELECT * FROM users WHERE age > 15 OR JSON_CONTAINS(parents, 50, '$.age') OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3378
3379 let name = ValueType::JsonString("necdet".to_string());
3380 let id = ValueType::Int32(1);
3381 let is_active = ValueType::Boolean(true);
3382
3383 let object = vec![("name", &name), ("id", &id), ("isActive", &is_active)];
3384
3385 let mysql_json_object = JsonValue::MysqlJsonObject(&object);
3386
3387 let where_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").where_("pic", "=", ValueType::String("".to_string())).json_contains("pic", mysql_json_object, Some("")).finish();
3388
3389 assert_eq!("SELECT * FROM users WHERE JSON_CONTAINS(pic, JSON_OBJECT('name', \"necdet\", 'id', 1, 'isActive', true), '$');", where_query_2)
3390 }
3391
3392 #[test]
3393 pub fn test_like_later_than_where_keywords(){
3394 let mut like_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap();
3395
3396 let like_query_1 = like_query_1.table("blogs")
3397 .where_("id", "=", ValueType::Int32(5))
3398 .like(["title", "description"].to_vec(), "hello")
3399 .finish();
3400
3401 assert_eq!(like_query_1, "SELECT * FROM blogs WHERE id = 5 AND (title LIKE '%hello%' OR description LIKE '%hello%');");
3402
3403 let mut like_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap();
3404
3405 let ins = vec![ValueType::Int32(1), ValueType::Int32(2), ValueType::Int32(3)];
3406 let like_query_2 = like_query_2.table("blogs")
3407 .where_in("id", &ins)
3408 .like(["title", "description", "keywords"].to_vec(), "necdet")
3409 .limit(10)
3410 .offset(0)
3411 .finish();
3412
3413 assert_eq!(like_query_2, "SELECT * FROM blogs WHERE id IN (1, 2, 3) AND (title LIKE '%necdet%' OR description LIKE '%necdet%' OR keywords LIKE '%necdet%') LIMIT 10 OFFSET 0;")
3414 }
3415
3416 #[test]
3417 pub fn test_ordering_functions(){
3418 let order_by_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by("id", "asc").order_by("weight", "desc").order_by("point", "asc").finish();
3419
3420 assert_eq!(order_by_query, "SELECT * FROM users ORDER BY id ASC, weight DESC, point ASC;");
3421
3422 let order_by_random_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_random().finish();
3423
3424 assert_eq!(order_by_random_query, "SELECT * FROM users ORDER BY RAND();");
3425
3426 let roles = ["admin", "moderator", "member", "guest"].to_vec();
3427 let field_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles.clone()).finish();
3428
3429 assert_eq!(field_query_1, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest');");
3430
3431 let field_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by("id", "asc").order_by_field("role", roles.clone()).finish();
3432
3433 assert_eq!(field_query_2, "SELECT * FROM users ORDER BY id ASC, FIELD(role, 'admin', 'moderator', 'member', 'guest');");
3434
3435 let field_query_3 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles.clone()).order_by("id", "asc").finish();
3436
3437 assert_eq!(field_query_3, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest'), id ASC;");
3438
3439 let field_query_4 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles).order_by_field("status", vec!["active", "banned", "unverified"]).finish();
3440
3441 assert_eq!(field_query_4, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest'), FIELD(status, 'active', 'banned', 'unverified');");
3442 }
3443
3444 #[test]
3445 pub fn test_unions(){
3446 let mut union_1 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap();
3447 union_1.table("users").where_("age", ">", ValueType::Int32(7));
3448
3449 let union_2 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap()
3450 .table("users")
3451 .where_("age", "<", ValueType::Int32(15))
3452 .union(vec![union_1])
3453 .finish();
3454
3455 assert_eq!(union_2, "(SELECT name, age, id FROM users WHERE age < 15) UNION (SELECT name, age, id FROM users WHERE age > 7);");
3456
3457 let mut union_1 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
3458 union_1.table("blogs").like(vec!["title"], "text");
3459
3460 let mut union_2 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
3461 union_2.table("blogs").like(vec!["description"], "some text");
3462
3463 let union_3 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap()
3464 .table("blogs")
3465 .where_("published", "=", ValueType::Boolean(true))
3466 .union_all(vec![union_1, union_2])
3467 .finish();
3468
3469 assert_eq!(union_3, "(SELECT id, title, description, published FROM blogs WHERE published = true) UNION ALL (SELECT id, title, description, published FROM blogs WHERE title LIKE '%text%') UNION ALL (SELECT id, title, description, published FROM blogs WHERE description LIKE '%some text%');");
3470 }
3471
3472 #[test]
3473 pub fn test_json_value(){
3474 let name = ValueType::JsonString("necdet".to_string());
3475 let age = ValueType::Int8(25);
3476 let id = ValueType::Int32(1);
3477
3478 let values = vec![("name", &name), ("age", &age), ("id", &id)];
3479
3480 let json_object = JsonValue::Object(&values);
3481
3482 assert_eq!("{\"name\": \"necdet\", \"age\": 25, \"id\": 1}", json_object.to_string());
3483
3484 let mysql_json_object = JsonValue::MysqlJsonObject(&values);
3485
3486 assert_eq!("JSON_OBJECT('name', \"necdet\", 'age', 25, 'id', 1)", mysql_json_object.to_string());
3487
3488 let name2 = ValueType::JsonString("cevdet".to_string());
3489 let age2 = ValueType::Int8(24);
3490 let id2 = ValueType::Int32(2);
3491
3492 let name3 = ValueType::JsonString("serap".to_string());
3493 let age3 = ValueType::Int8(21);
3494 let id3 = ValueType::Int32(3);
3495
3496 let object1 = vec![("name", &name), ("age", &age), ("id", &id)];
3497 let object2 = vec![("name", &name2), ("age", &age2), ("id", &id2)];
3498 let object3 = vec![("name", &name3), ("age", &age3), ("id", &id3)];
3499
3500 let objects = vec![object1, object2, object3];
3501
3502 let json_array = JsonValue::ObjectArray(&objects);
3503
3504 assert_eq!("[{\"name\": \"necdet\", \"age\": 25, \"id\": 1}, {\"name\": \"cevdet\", \"age\": 24, \"id\": 2}, {\"name\": \"serap\", \"age\": 21, \"id\": 3}]", json_array.to_string());
3505 }
3506
3507 #[test]
3508 pub fn test_json_array_append(){
3509 let lesson = ("lesson", &ValueType::String("math".to_string()));
3510 let point = ("point", &ValueType::Int32(100));
3511
3512 let values = vec![lesson, point];
3513
3514 let object = JsonValue::MysqlJsonObject(&values);
3515
3516 let query = QueryBuilder::update().unwrap()
3517 .table("users")
3518 .json_array_append("points", Some(""), object.clone())
3519 .where_("id", "=", ValueType::Int8(1))
3520 .finish();
3521
3522 assert_eq!("UPDATE users SET points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3523
3524 let query = QueryBuilder::update().unwrap()
3525 .table("users")
3526 .set("status", ValueType::String("passed".to_string()))
3527 .json_array_append("points", Some(""), object)
3528 .where_("id", "=", ValueType::Int8(1))
3529 .finish();
3530
3531 assert_eq!("UPDATE users SET status = 'passed', points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3532 }
3533
3534 #[test]
3535 pub fn test_json_remove() {
3536 let query = QueryBuilder::update().unwrap()
3537 .table("blogs")
3538 .json_remove("likes", vec!["[10]"])
3539 .where_("blog_id", "=", ValueType::Int32(20))
3540 .finish();
3541
3542 assert_eq!(query, "UPDATE blogs SET likes = JSON_REMOVE(likes, '$[10]') WHERE blog_id = 20;");
3543
3544 let query = QueryBuilder::update().unwrap()
3545 .table("blogs")
3546 .set("blabla", ValueType::Int32(50))
3547 .json_remove("likes", vec!["[10]", "[11]", "[12]"])
3548 .where_("blog_id", "=", ValueType::Int32(20))
3549 .finish();
3550
3551 println!("{}", query)
3552 }
3553
3554 #[test]
3555 pub fn test_json_set_and_json_replace(){
3556 let lesson = ("lesson", &ValueType::String("math".to_string()));
3557 let point = ("point", &ValueType::Int32(100));
3558
3559 let values = vec![lesson, point];
3560
3561 let object = JsonValue::MysqlJsonObject(&values);
3562
3563 let query = QueryBuilder::update().unwrap()
3564 .table("users")
3565 .json_set("points", "[0]", object)
3566 .where_("id", "=", ValueType::Int32(1))
3567 .finish();
3568
3569 assert_eq!("UPDATE users SET points = JSON_SET(points, '$[0]', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3570
3571 let value = ValueType::Int32(100);
3572 let value = JsonValue::Initial(&value);
3573
3574 let query = QueryBuilder::update().unwrap()
3575 .table("users")
3576 .json_replace("points", "[0].point", value)
3577 .where_("id", "=", ValueType::Int32(1))
3578 .finish();
3579
3580 assert_eq!("UPDATE users SET points = JSON_REPLACE(points, '$[0].point', 100) WHERE id = 1;", query)
3581 }
3582
3583 #[test]
3584 pub fn test_json_value_initial_bugfix(){
3585 let file_name_val = ValueType::JsonString("chemistry".to_string());
3586 let file_name_val = JsonValue::Initial(&file_name_val);
3587
3588 let query = QueryBuilder::select(vec!["lesson_points"]).unwrap()
3589 .json_extract("points", &format!("[{}]", 2), Some("point"))
3590 .table("students")
3591 .where_("id", "=", ValueType::Int32(5))
3592 .and("adsf", "=", ValueType::Null)
3593 .json_contains("points", file_name_val, Some(&format!("[{}].name", 0)))
3594 .finish();
3595
3596 assert_eq!("SELECT JSON_EXTRACT(points, '$[2]') AS point FROM students WHERE id = 5 AND JSON_CONTAINS(points, '\"chemistry\"', '$[0].name');", query);
3597 }
3598}