qubl/
lib.rs

1/// Struct that benefits to build queries for interactions with rdbms's.
2#[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
11/// Implementations For QueryBuilder.
12impl<'a> QueryBuilder<'a> {
13    /// Select constructor. Use it if you want to build a Select Query.
14    /// 
15    /// ```rust
16    /// 
17    /// use qubl::{QueryBuilder, ValueType};
18    /// 
19    /// fn main(){
20    ///     let query = QueryBuilder::select(vec!["*"]).unwrap();
21    /// }
22    /// 
23    /// ```
24    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    /// Delete constructor. Use it if you want to build a Delete Query.
74    /// 
75    /// ```rust
76    /// 
77    /// use qubl::{QueryBuilder, ValueType};
78    /// 
79    /// fn main(){
80    ///     let query = QueryBuilder::delete().unwrap();
81    /// }
82    /// 
83    /// ```
84    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    /// Update constructor. Use it if you want to build a Update Query.
95    /// 
96    /// ```rust
97    /// 
98    /// use qubl::{QueryBuilder, ValueType};
99    /// 
100    /// fn main(){
101    ///     let query = QueryBuilder::update().unwrap();
102    /// }
103    /// 
104    /// ```
105    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    /// Insert constructor. Use it if you want to build a Insert Query.
116    ///     
117    /// ```rust
118    /// 
119    /// use qubl::{QueryBuilder, ValueType};
120    /// 
121    /// fn main(){
122    ///     let fields = vec!["id", "age", "name"];
123    ///     let values = vec![ValueType::Int32(5), ValueType::Int64(25), ValueType::String("necdet".to_string())]
124    /// 
125    ///     let query = QueryBuilder::insert(fields, values).unwrap();
126    /// }
127    /// 
128    /// ```
129    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    /// define the table. It should came after the constructors.
190    /// 
191    /// ```rust
192    /// 
193    /// use qubl::{QueryBuilder, ValueType};
194    /// 
195    /// fn main(){
196    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users");
197    /// }
198    /// 
199    /// ```
200    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    /// Count constructor. Use it if you want to learn to length of a table.
235    ///     
236    /// ```rust
237    /// 
238    /// use qubl::{QueryBuilder, ValueType};
239    /// 
240    /// fn main(){
241    ///     let query = QueryBuilder::count("*", Some("length")).table("users");
242    /// }
243    /// 
244    /// ```
245    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    /// add the "WHERE" keyword with it's synthax.
262    /// ```rust
263    /// 
264    /// use qubl::{QueryBuilder, ValueType};
265    /// 
266    /// fn main(){
267    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_("id", "=", ValueType::Int32(5)).finish();
268    /// 
269    ///     assert_eq!(query, "SELECT * FROM users WHERE id = 5;")
270    /// }
271    /// 
272    /// ```
273    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    /// It adds the "IN" keyword with it's synthax. Don't use ".where_cond()" method if you use it.
302    ///     
303    /// ```rust
304    /// 
305    /// use qubl::{QueryBuilder, ValueType};
306    /// 
307    /// fn main(){
308    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
309    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_in("id", &ins).finish();
310    /// 
311    ///     assert_eq!(query, "SELECT * FROM users WHERE id IN (1, 5, 10);")
312    /// }
313    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::WhereIn);
334        self
335    }
336
337    /// It adds the "NOT IN" keyword with it's synthax. Don't use ".where_cond()" method if you use it.
338    ///     
339    /// ```rust
340    /// 
341    /// use qubl::{QueryBuilder, ValueType};
342    /// 
343    /// fn main(){
344    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
345    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_not_in("id", &ins).finish();
346    /// 
347    ///     assert_eq!(query, "SELECT * FROM users WHERE id NOT IN (1, 5, 10);")
348    /// }
349     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::WhereNotIn);
370        self
371    }
372
373    /// It adds the "IN" keyword with it's synthax and an empty condition, use it if you want to give more complex condition to "IN" keyword. Don't use ".where_cond()" with it.
374    ///
375    /// ```rust
376    /// 
377    /// use qubl::{QueryBuilder, ValueType};
378    /// 
379    /// fn main(){
380    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
381    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_in_custom("id", "1, 5, 10").finish();
382    /// 
383    ///     assert_eq!(query, "SELECT * FROM users WHERE id IN (1, 5, 10);")
384    /// }
385    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::WhereIn);
389        self
390    }
391
392    /// It adds the "NOT IN" keyword with it's synthax and an empty condition, use it if you want to give more complex condition to "NOT IN" keyword. Don't use ".where_cond()" with it.
393    ///    
394    /// ```rust
395    /// 
396    /// use qubl::{QueryBuilder, ValueType};
397    /// 
398    /// fn main(){
399    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
400    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_not_in_custom("id", "1, 5, 10").finish();
401    /// 
402    ///     assert_eq!(query, "SELECT * FROM users WHERE id NOT IN (1, 5, 10);")
403    /// }
404    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::WhereNotIn);
408
409        self
410    }
411
412
413    /// It adds the "IN" keyword with it's synthax, with 'AND' keyword except 'WHERE'.
414    ///     
415    /// ```rust
416    /// 
417    /// use qubl::{QueryBuilder, ValueType};
418    /// 
419    /// fn main(){
420    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
421    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
422    ///                              .table("users")
423    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
424    ///                              .and_in("id", &ins)
425    ///                              .finish();
426    /// 
427    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' AND id IN (1, 5, 10);")
428    /// }
429    pub fn and_in(&mut self, column: &str, ins: &Vec<ValueType>) -> &mut Self {
430        match ins.len() {
431            0 => panic!("you cannot pass an empty vector to the ins argument"),
432            _ => ()
433        }
434
435        self.query = format!("{} AND {} IN (", self.query, column);
436
437        let length_of_ins = ins.len();
438
439        for (index, value) in ins.into_iter().enumerate() {
440            if index + 1 == length_of_ins {
441                self.query = format!("{}{})", self.query, value);
442                    
443                continue;
444            }
445
446            self.query = format!("{}{}, ", self.query, value);
447        }
448
449        self.list.push(KeywordList::AndIn);
450        self
451    }
452
453
454    /// It adds the "NOT IN" keyword with it's synthax, with 'AND' keyword except 'WHERE'.
455    ///     
456    /// ```rust
457    /// 
458    /// use qubl::{QueryBuilder, ValueType};
459    /// 
460    /// fn main(){
461    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
462    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
463    ///                              .table("users")
464    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
465    ///                              .and_not_in("id", &ins)
466    ///                              .finish();
467    /// 
468    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' AND id NOT IN (1, 5, 10);")
469    /// }
470    pub fn and_not_in(&mut self, column: &str, ins: &Vec<ValueType>) -> &mut Self {
471        match ins.len() {
472            0 => panic!("you cannot pass an empty vector to the ins argument"),
473            _ => ()
474        }
475
476        self.query = format!("{} AND {} NOT IN (", self.query, column);
477
478        let length_of_ins = ins.len();
479
480        for (index, value) in ins.into_iter().enumerate() {
481            if index + 1 == length_of_ins {
482                self.query = format!("{}{})", self.query, value);
483                    
484                continue;
485            }
486
487            self.query = format!("{}{}, ", self.query, value);
488        }
489
490        self.list.push(KeywordList::AndNotIn);
491        self
492    }
493
494    /// It adds the "IN" keyword with it's synthax, with 'AND' keyword except 'WHERE'.
495    ///     
496    /// ```rust
497    /// 
498    /// use qubl::{QueryBuilder, ValueType};
499    /// 
500    /// fn main(){
501    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
502    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
503    ///                              .table("users")
504    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
505    ///                              .and_in_custom("id", "1, 5, 10")
506    ///                              .finish();
507    /// 
508    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' AND id IN (1, 5, 10);")
509    /// }
510    pub fn and_in_custom(&mut self, column: &str, query: &str) -> &mut Self {
511        self.query = format!("{} AND {} IN ({})", self.query, column, query);
512
513        self.list.push(KeywordList::AndIn);
514        self
515    }
516
517    /// It adds the "IN" keyword with it's synthax, with 'AND' keyword except 'WHERE'.
518    ///     
519    /// ```rust
520    /// 
521    /// use qubl::{QueryBuilder, ValueType};
522    /// 
523    /// fn main(){
524    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
525    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
526    ///                              .table("users")
527    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
528    ///                              .and_not_in_custom("id", "1, 5, 10")
529    ///                              .finish();
530    /// 
531    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' AND id NOT IN (1, 5, 10);")
532    /// }
533    pub fn and_not_in_custom(&mut self, column: &str, query: &str) -> &mut Self {
534        self.query = format!("{} AND {} NOT IN ({})", self.query, column, query);
535
536        self.list.push(KeywordList::AndNotIn);
537
538        self
539    }
540
541    /// It adds the "IN" keyword with it's synthax, with 'OR' keyword except 'WHERE'.
542    ///     
543    /// ```rust
544    /// 
545    /// use qubl::{QueryBuilder, ValueType};
546    /// 
547    /// fn main(){
548    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
549    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
550    ///                              .table("users")
551    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
552    ///                              .or_in("id", &ins)
553    ///                              .finish();
554    /// 
555    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' OR id IN (1, 5, 10);")
556    /// }
557    pub fn or_in(&mut self, column: &str, ins: &Vec<ValueType>) -> &mut Self {
558        match ins.len() {
559            0 => panic!("you cannot pass an empty vector to the ins argument"),
560            _ => ()
561        }
562
563        self.query = format!("{} OR {} IN (", self.query, column);
564
565        let length_of_ins = ins.len();
566
567        for (index, value) in ins.into_iter().enumerate() {
568            if index + 1 == length_of_ins {
569                self.query = format!("{}{})", self.query, value);
570                    
571                continue;
572            }
573
574            self.query = format!("{}{}, ", self.query, value);
575        }
576
577        self.list.push(KeywordList::AndIn);
578        self
579    }
580
581    /// It adds the "NOT IN" keyword with it's synthax, with 'OR' keyword except 'WHERE'.
582    ///     
583    /// ```rust
584    /// 
585    /// use qubl::{QueryBuilder, ValueType};
586    /// 
587    /// fn main(){
588    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
589    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
590    ///                              .table("users")
591    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
592    ///                              .or_not_in("id", &ins)
593    ///                              .finish();
594    /// 
595    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' OR id NOT IN (1, 5, 10);")
596    /// }
597    pub fn or_not_in(&mut self, column: &str, ins: &Vec<ValueType>) -> &mut Self {
598        match ins.len() {
599            0 => panic!("you cannot pass an empty vector to the ins argument"),
600            _ => ()
601        }
602
603        self.query = format!("{} OR {} NOT IN (", self.query, column);
604
605        let length_of_ins = ins.len();
606
607        for (index, value) in ins.into_iter().enumerate() {
608            if index + 1 == length_of_ins {
609                self.query = format!("{}{})", self.query, value);
610                    
611                continue;
612            }
613
614            self.query = format!("{}{}, ", self.query, value);
615        }
616
617        self.list.push(KeywordList::AndNotIn);
618        self
619    }
620
621    /// It adds the "IN" keyword with it's synthax, with 'AND' keyword except 'WHERE'.
622    ///     
623    /// ```rust
624    /// 
625    /// use qubl::{QueryBuilder, ValueType};
626    /// 
627    /// fn main(){
628    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
629    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
630    ///                              .table("users")
631    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
632    ///                              .or_in_custom("id", "1, 5, 10")
633    ///                              .finish();
634    /// 
635    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' OR id IN (1, 5, 10);")
636    /// }
637    pub fn or_in_custom(&mut self, column: &str, query: &str) -> &mut Self {
638        self.query = format!("{} OR {} IN ({})", self.query, column, query);
639
640        self.list.push(KeywordList::AndIn);
641        self
642    }
643
644    /// It adds the "IN" keyword with it's synthax, with 'AND' keyword except 'WHERE'.
645    ///     
646    /// ```rust
647    /// 
648    /// use qubl::{QueryBuilder, ValueType};
649    /// 
650    /// fn main(){
651    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
652    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
653    ///                              .table("users")
654    ///                              .where_("class", "=", ValueType::String("10/c".to_string()))
655    ///                              .or_not_in_custom("id", "1, 5, 10")
656    ///                              .finish();
657    /// 
658    ///     assert_eq!(query, "SELECT * FROM users WHERE class = '10/c' OR id NOT IN (1, 5, 10);")
659    /// }
660    pub fn or_not_in_custom(&mut self, column: &str, query: &str) -> &mut Self {
661        self.query = format!("{} OR {} NOT IN ({})", self.query, column, query);
662
663        self.list.push(KeywordList::AndNotIn);
664
665        self
666    }
667
668    /// it benefits to set timezone when you make your query. It's very flexible, always put on very beginning of the query, you can use it later than any other method.
669    pub fn time_zone(&mut self, timezone: Timezone) -> &mut Self {
670        self.query = format!("SET time_zone = {}; {}", timezone, self.query);
671
672        self.list.push(KeywordList::Timezone);
673        self
674    }
675
676    /// it benefits to set global timezone when you make your query. It's very flexible, always put on very beginning of the query, you can use it later than any other method.
677    pub fn global_time_zone(&mut self, timezone: Timezone) -> &mut Self {
678        self.query = format!("SET GLOBAL time_zone = {}; {}", timezone, self.query);
679
680        self.list.push(KeywordList::GlobalTimezone);
681        self
682    }
683
684    /// It adds the "OR" keyword with it's synthax. Warning: It's not ready yet to chaining "AND" and "OR" keywords, for now, applying that kind of complex query use ".append_custom()" method instead.
685    ///
686    /// ```rust
687    /// 
688    /// use qubl::{QueryBuilder, ValueType};
689    /// 
690    /// fn main(){
691    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
692    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_("id", "=", ValueType::Int32(10)).or("name", "=", ValueType::String("necdet".to_string())).finish();
693    /// 
694    ///     assert_eq!(query, "SELECT * FROM users WHERE id = 10 OR name = 'necdet';")
695    /// }
696   pub fn or(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
697        match self.sanitize_column(column) {
698            Ok(_) => (),
699            Err(error) => panic!("{}", error)
700        }
701
702        match Self::sanitize_mark(mark) {
703            Ok(_) => (),
704            Err(error) => panic!("{}", error)
705        }
706
707        match self.sanitize_input(&value) {
708            Ok(_) => (),
709            Err(error) => panic!("{}", error)
710        }
711
712        self.query = format!("{} OR {} {} {}", self.query, column, mark, value);
713
714
715        self.list.push(KeywordList::Or);
716
717        self
718    }
719
720    /// It adds the "SET" keyword with it's synthax.
721    /// 
722    /// ```rust
723    /// 
724    /// use qubl::{QueryBuilder, ValueType};
725    /// 
726    /// fn main(){
727    ///     let query = QueryBuilder::update().unwrap()
728    ///                              .table("users")
729    ///                              .set("name", ValueType::String("arda".to_string()))
730    ///                              .where_("id", "=", ValueType::Int32(1))
731    ///                              .finish();
732    /// 
733    ///     assert_eq!(query, "UPDATE users SET name = 'arda' WHERE id = 1;")
734    /// }
735    /// 
736    /// ```
737    pub fn set(&mut self, column: &str, value: ValueType) -> &mut Self {
738        match self.hq {
739            Some(_) => (),
740            None => self.hq = Some(Self::load_hqs())
741        }
742
743        match self.sanitize_column(column) {
744            Ok(_) => (),
745            Err(error) => panic!("{}", error)
746        }
747
748        match self.sanitize_input(&value) {
749            Ok(_) => (),
750            Err(error) => panic!("{}", error)
751        }
752
753        match self.list.last() {
754            Some(keyword) => {
755                match keyword {
756                    KeywordList::Set => self.query = format!("{}, {} = {}", self.query, column, value),
757                    _ => self.query = format!("{} SET {} = {}", self.query, column, value)
758                }
759            },
760            None => panic!("that's impossible to come here.")
761        }
762
763        self.list.push(KeywordList::Set);
764
765        self
766    }
767
768    /// It adds the "AND" keyword with it's synthax. Warning: It's not ready yet to chaining "OR" and "AND" keywords, for now, applying that kind of complex query use ".append_custom()" method instead.
769    ///
770    /// ```rust
771    /// 
772    /// use qubl::{QueryBuilder, ValueType};
773    /// 
774    /// fn main(){
775    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
776    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_("id", "=", ValueType::Int32(10)).and("name", "=", ValueType::String("necdet".to_string())).finish();
777    /// 
778    ///     assert_eq!(query, "SELECT * FROM users WHERE id = 10 AND name = 'necdet';")
779    /// }
780    pub fn and(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
781        match self.sanitize_column(column) {
782            Ok(_) => (),
783            Err(error) => panic!("{}", error)
784        }
785
786        match Self::sanitize_mark(mark) {
787            Ok(_) => (),
788            Err(error) => panic!("{}", error)
789        }
790
791        match self.sanitize_input(&value) {
792            Ok(_) => (),
793            Err(error) => panic!("{}", error)
794        }
795
796        self.query = format!("{} AND {} {} {}", self.query, column, mark, value);
797
798        self.list.push(KeywordList::And);
799
800        self
801    }
802
803    /// It adds the "OFFSET" keyword with it's synthax. Be careful about it's alignment with "LIMIT" keyword.
804    ///     
805    /// ```rust
806    /// 
807    /// use qubl::{QueryBuilder, ValueType};
808    /// 
809    /// fn main(){
810    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
811    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_("id", "=", ValueType::Int32(10)).limit(5).offset(0).finish();
812    /// 
813    ///     assert_eq!(query, "SELECT * FROM users WHERE id = 10 LIMIT 5 OFFSET 0;")
814    /// }
815    pub fn offset(&mut self, offset: i32) -> &mut Self {
816        self.query = format!("{} OFFSET {}", self.query, offset);
817
818        self.list.push(KeywordList::Offset);
819
820        self
821    }
822
823    /// It adds the "LIMIT" keyword with it's synthax.
824    /// 
825    /// ```rust
826    /// 
827    /// use qubl::{QueryBuilder, ValueType};
828    /// 
829    /// fn main(){
830    ///     let ins = vec![ValueType::Int16(1), ValueType::Int64(5), ValueType::Int32(10)];
831    ///     let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").where_("id", "=", ValueType::Int32(10)).limit(5).offset(0).finish();
832    /// 
833    ///     assert_eq!(query, "SELECT * FROM users WHERE id = 10 LIMIT 5 OFFSET 0;")
834    /// }
835    pub fn limit(&mut self, limit: i32) -> &mut Self {
836        self.query = format!("{} LIMIT {}", self.query, limit);
837
838        self.list.push(KeywordList::Limit);
839
840        self
841    }
842
843    /// It adds the "LIKE" keyword with it's synthax.
844    /// ```rust
845    /// 
846    /// use qubl::{QueryBuilder, ValueType};
847    /// 
848    /// fn main(){
849    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
850    ///                              .table("blogs")
851    ///                              .like(vec!["description", "title"], "qubl is awesome!")
852    ///                              .finish();
853    /// 
854    ///     assert_eq!(query, "SELECT * FROM blogs WHERE description LIKE '%qubl is awesome!%' OR title LIKE '%qubl is awesome!%';")
855    /// }
856    /// 
857    /// // it has more niche and different usages, for them check the tests.
858    pub fn like(&mut self, columns: Vec<&str>, operand: &str) -> &mut Self {
859        match columns.len() {
860            0 => panic!("you cannot pass an empty vector to the columns"),
861            _ => ()
862        }
863
864        let hqs = match self.hq {
865            Some(hqs) => hqs,
866            None => {
867                let load_hqs = Self::load_hqs();
868                self.hq = Some(load_hqs);
869
870                load_hqs
871            }
872        };
873
874        match Self::sanitize_columns(&columns, hqs) {
875            Ok(_) => {
876                match self.sanitize_str(operand){
877                    Ok(_) => (),
878                    Err(error) => {
879                        println!("That Error Occured in like method: {}", error);
880                
881                        self.list.push(KeywordList::Like);
882        
883                        return self
884                    }
885                }
886        
887                match self.list.last() {
888                    Some(keyword) => {
889                        if keyword == &KeywordList::Where || keyword == &KeywordList::WhereIn || keyword == &KeywordList::WhereNotIn {
890                            let length_of_columns = columns.len();
891        
892                            for (i, column) in columns.into_iter().enumerate() {
893                                match length_of_columns {
894                                    1 => {
895                                        if i == 0 {
896                                            self.query = format!("{} AND {} LIKE '%{}%'", self.query, column, operand)
897                                        }  
898                                    },
899                                    _ => {
900                                        if i == 0 {
901                                            self.query = format!("{} AND ({} LIKE '%{}%'", self.query, column, operand)
902                                        } else if i + 1 == length_of_columns {
903                                            self.query = format!("{} OR {} LIKE '%{}%')", self.query, column, operand)
904                                        } else {
905                                            self.query = format!("{} OR {} LIKE '%{}%'", self.query, column, operand)
906                                        }
907                                    }
908                                }
909                            }
910                        } else {
911                            for (i, column) in columns.into_iter().enumerate() {
912                                if i == 0 {
913                                    self.query = format!("{} WHERE {} LIKE '%{}%'", self.query, column, operand);
914                                } else {
915                                    self.query = format!("{} OR {} LIKE '%{}%'", self.query, column, operand);
916                                }
917                            }
918                        }
919                    },
920                    None => panic!("Our current implementation does not support to use '.like()' later not other than WHERE, IN or NOT IN queries.")
921                }
922
923                return self
924            },
925            Err(error) => panic!("That error occured in '.like()' method: {}", error)
926        }
927    }
928
929    /// It adds the "ORDER BY" keyword with it's synthax. It only accepts "ASC", "DESC", "asc", "desc" values.
930    /// ```rust
931    /// 
932    /// use qubl::{QueryBuilder, ValueType};
933    /// 
934    /// fn main(){
935    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
936    ///                              .table("users")
937    ///                              .where_("age", ">", ValueType::Int32(25))
938    ///                              .order_by("id", "ASC")
939    ///                              .limit(5)
940    ///                              .offset(0)
941    ///                              .finish();
942    /// 
943    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY id ASC LIMIT 5 OFFSET 0;")
944    /// }
945    pub fn order_by(&mut self, column: &str, mut ordering: &str) -> &mut Self {
946        match self.sanitize_column(column) {
947            Ok(_) => (),
948            Err(error) => {
949                println!("{}", error);
950
951                self.list.push(KeywordList::OrderBy);
952
953                return self
954            }
955        }
956
957        match ordering {
958            "asc" => ordering = "ASC",
959            "desc" => ordering = "DESC",
960            "ASC" => ordering = "ASC",
961            "DESC" => ordering = "DESC",
962            &_ => panic!("Panicking in order_by method: There is no other ordering options than ASC or DESC.")
963        }
964
965        match self.list.last() {
966            Some(keyword) => match keyword {
967                KeywordList::OrderBy | KeywordList::Field => self.query = format!("{}, {} {}", self.query, column, ordering),
968                _ => self.query = format!("{} ORDER BY {} {}", self.query, column, ordering)
969            },
970            None => panic!("It's almost impossible you to come here.")
971        }
972
973        self.list.push(KeywordList::OrderBy);
974
975        self
976    }
977
978    /// A practical method that adds a query for shuffling the lines.
979    /// ```rust
980    /// 
981    /// use qubl::{QueryBuilder, ValueType};
982    /// 
983    /// fn main(){
984    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
985    ///                              .table("users")
986    ///                              .where_("age", ">", ValueType::Int32(25))
987    ///                              .order_random()
988    ///                              .limit(5)
989    ///                              .offset(0)
990    ///                              .finish();
991    /// 
992    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY RAND() LIMIT 5 OFFSET 0;")
993    /// }
994    pub fn order_random(&mut self) -> &mut Self {
995        if self.query.contains("ORDER BY") {
996            panic!("Error in order_random method: you cannot add ordering option twice on a query.");
997        }
998
999        self.query = format!("{} ORDER BY RAND()", self.query);
1000        self.list.push(KeywordList::OrderBy);
1001
1002        self
1003    }
1004
1005    /// Adds "FIELD()" function with it's synthax. It's used on ordering depending on strings.
1006    /// ```rust
1007    /// 
1008    /// use qubl::{QueryBuilder, ValueType};
1009    /// 
1010    /// fn main(){
1011    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
1012    ///                              .table("users")
1013    ///                              .where_("age", ">", ValueType::Int32(25))
1014    ///                              .order_by_field("role", vec!["admin", "member", "observer"])
1015    ///                              .limit(5)
1016    ///                              .offset(0)
1017    ///                              .finish();
1018    /// 
1019    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0;")
1020    /// }
1021    pub fn order_by_field(&mut self, column: &str, ordering: Vec<&str>) -> &mut Self {
1022        match ordering.len() {
1023            0 => panic!("you cannot pass an empty vector to the ordering argument"),
1024            _ => ()
1025        }
1026
1027        match self.list.last() {
1028            Some(keyword) => match keyword {
1029                KeywordList::OrderBy => {
1030                    let mut split_the_query = self.query.split(" ORDER BY ");
1031                
1032                    self.query = format!("{} ORDER BY {}, FIELD({}", split_the_query.nth(0).unwrap(), split_the_query.nth(0).unwrap(), column);
1033
1034                    for item in ordering {
1035                        self.query = format!("{}, '{}'", self.query, item)
1036                    }
1037
1038                    self.query = format!("{})", self.query);
1039                },
1040                KeywordList::Field => {
1041                    self.query = format!("{}, FIELD({}", self.query, column);
1042
1043                    for item in ordering {
1044                        self.query = format!("{}, '{}'", self.query, item)
1045                    }
1046
1047                    self.query = format!("{})", self.query);
1048                },
1049                _ => {
1050                    let mut new_part_of_query = format!("ORDER BY FIELD({}", column);
1051
1052                    for item in ordering {
1053                        new_part_of_query = format!("{}, '{}'", new_part_of_query, item)
1054                    }
1055
1056                    self.query = format!("{} {})", self.query, new_part_of_query);
1057                }
1058            },
1059            None => panic!("It's almost impossible you to come here.")
1060        }
1061
1062        self.list.push(KeywordList::Field);
1063
1064        self
1065    }
1066
1067    /// It adds the "GROUP BY" keyword with it's Synthax.
1068    pub fn group_by(&mut self, column: &str) -> &mut Self {
1069        self.query = format!("{} GROUP BY {}", self.query, column);
1070
1071        self.list.push(KeywordList::GroupBy);
1072
1073        self
1074    }
1075
1076    pub fn having(&mut self, column: &str, mark: &str, value: ValueType) -> &mut Self {
1077        match self.sanitize_column(column) {
1078            Ok(_) => (),
1079            Err(error) => panic!("{}", error)
1080        }
1081
1082        match Self::sanitize_mark(mark) {
1083            Ok(_) => (),
1084            Err(error) => panic!("{}", error)
1085        }
1086
1087        match self.sanitize_input(&value) {
1088            Ok(_) => (),
1089            Err(error) => panic!("{}", error)
1090        }
1091
1092        self.query = format!("{} HAVING {} {} {}", self.query, column, mark, value);
1093
1094        self.list.push(KeywordList::Having);
1095
1096        self
1097    }
1098
1099
1100    /// it adds the `UNION` keyword and its synthax. You can pass multiple queries to union with:
1101    /// 
1102    /// ```rust
1103    /// 
1104    /// use qubl::{QueryBuilder, ValueType};
1105    /// 
1106    /// fn main(){
1107    ///     let mut union_1 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap();
1108    ///     union_1.table("users").where_("age", ">", ValueType::Int32(7));
1109    ///
1110    ///     let union_2 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap()
1111    ///                                .table("users")
1112    ///                                .where_("age", "<", ValueType::Int32(15))
1113    ///                                .union(vec![union_1])
1114    ///                                .finish();
1115    ///
1116    ///     assert_eq!(union_2, "(SELECT name, age, id FROM users WHERE age < 15) UNION (SELECT name, age, id FROM users WHERE age > 7);");
1117    /// }
1118    /// 
1119    /// ```
1120    pub fn union(&mut self, others: Vec<QueryBuilder<'_>>) -> &mut Self {
1121        match self.list.last() {
1122            Some(keyword) => {
1123                match keyword {
1124                    KeywordList::Union | KeywordList::UnionAll => {
1125                        for other in others {
1126                            self.query = format!("{} UNION ({})", self.query, other.query)
1127                        }
1128                    },
1129                    _ => {
1130                        self.query = format!("({})", self.query);
1131                        
1132                        for other in others {
1133                            self.query = format!("{} UNION ({})", self.query, other.query)
1134                        }
1135                    }
1136                }
1137            },
1138            None => panic!("it's impossible to came here!")
1139        }
1140
1141        self.list.push(KeywordList::Union);
1142
1143        self
1144    }
1145
1146
1147    /// it adds the `UNION` keyword and its synthax. You can pass multiple queries to union with:
1148    /// 
1149    /// ```rust
1150    /// 
1151    /// use qubl::{QueryBuilder, ValueType};
1152    /// 
1153    /// fn main(){
1154    ///     let mut union_1 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
1155    ///     union_1.table("blogs").like(vec!["title"], "text");
1156    ///
1157    ///     let mut union_2 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
1158    ///     union_2.table("blogs").like(vec!["description"], "some text");
1159    ///
1160    ///     let union_3 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap()
1161    ///                                .table("blogs")
1162    ///                                .where_("published", "=", ValueType::Boolean(true))
1163    ///                                .union_all(vec![union_1, union_2])
1164    ///                                .finish();
1165    ///
1166    ///     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%');");
1167    /// }
1168    /// 
1169    /// ```
1170    /// 
1171    pub fn union_all(&mut self, others: Vec<QueryBuilder<'_>>) -> &mut Self {
1172        match self.list.last() {
1173            Some(keyword) => {
1174                match keyword {
1175                    KeywordList::Union | KeywordList::UnionAll => {
1176                        for other in others {
1177                            self.query = format!("{} UNION ALL ({})", self.query, other.query)
1178                        }
1179                    },
1180                    _ => {
1181                        self.query = format!("({})", self.query);
1182                        
1183                        for other in others {
1184                            self.query = format!("{} UNION ALL ({})", self.query, other.query)
1185                        }
1186                    }
1187                }
1188            },
1189            None => panic!("it's impossible to came here!")
1190        }
1191
1192        self.list.push(KeywordList::UnionAll);
1193
1194        self
1195    }
1196
1197    /// A wildcard method that gives you the chance to write a part of your query. Warning, it does not add any keyword to builder, i'll encourage to add proper keyword to it with `.append_keyword()` method for your custom query, otherwise you should continue building your query by yourself with that function, or you've to be prepared to encounter bugs.  
1198    /// 
1199    /// ```rust
1200    /// 
1201    /// use qubl::{QueryBuilder, ValueType};
1202    /// 
1203    /// fn main(){
1204    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
1205    ///                              .table("users")
1206    ///                              .append_custom("WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0")
1207    ///                              .finish();
1208    /// 
1209    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0;")
1210    /// }
1211    /// ```
1212    /// 
1213    pub fn append_custom(&mut self, query: &str) -> &mut Self {
1214        self.query = format!("{} {}", self.query, query);
1215
1216        self
1217    }
1218
1219    /// A wildcard method that benefits you to append a keyword to the keyword list, so the QueryBuilder can build your queries properly, later than you appended your custom string to your query. It should be used with `.append_custom()` method. 
1220    /// 
1221    /// ```rust
1222    /// 
1223    /// use qubl::{QueryBuilder, ValueType, KeywordList};
1224    /// 
1225    /// fn main(){
1226    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
1227    ///                              .table("users")
1228    ///                              .append_custom("WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0")
1229    ///                              .append_keyword(KeywordList::Where)
1230    ///                              .append_keyword(KeywordList::Field)
1231    ///                              .append_keyword(KeywordList::Limit)
1232    ///                              .append_keyword(KeywordList::Offset)
1233    ///                              .finish();
1234    /// 
1235    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0;")
1236    /// }
1237    /// ```
1238    /// 
1239    pub fn append_keyword(&mut self, keyword: KeywordList) -> &mut Self {
1240        self.list.push(keyword);
1241
1242        self
1243    }
1244    
1245    /// It applies "JSON_EXTRACT()" mysql function with it's Synthax. If you encounter any syntactic bugs or deficiencies about that function, please report it via opening an issue.
1246    /// 
1247    /// ```rust
1248    /// 
1249    /// use qubl::{QueryBuilder, ValueType};
1250    /// 
1251    /// fn main(){
1252    ///     let query = QueryBuilder::select(["*"].to_vec()).unwrap()
1253    ///                              .json_extract("articles", "[0]", Some("blog1"))
1254    ///                              .json_extract("articles", "[1]", Some("blog2"))
1255    ///                              .json_extract("articles", "[2]", Some("blog3"))
1256    ///                              .table("users")
1257    ///                              .where_("published", "=", ValueType::Int32(1))
1258    ///                              .finish();
1259    /// 
1260    ///     assert_eq!(query, "SELECT JSON_EXTRACT(articles, '$[0]') AS blog1, JSON_EXTRACT(articles, '$[1]') AS blog2, JSON_EXTRACT(articles, '$[2]') AS blog3 FROM users WHERE published = 1;")
1261    /// }
1262    /// 
1263    /// ```
1264    pub fn json_extract(&mut self, haystack: &str, needle: &str, _as: Option<&str>) -> &mut Self {
1265        match self.list.last() {
1266            Some(keyword) => {
1267                match keyword {
1268                    KeywordList::Where => {
1269                        if _as.is_some() {
1270                            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.");
1271                        }
1272
1273                        match self.table.as_str() == haystack {
1274                            true => {
1275                                let mut split_the_query = self.query.split(haystack);
1276                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1277
1278                                self.query = format!("SELECT{}{}{}", self.table, string_for_replace, split_the_query.nth(2).unwrap()) 
1279                            },
1280                            false => {
1281                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1282
1283                                self.query = self.query.replace(haystack,&string_for_replace)
1284                            }
1285                        }
1286                    },
1287                    KeywordList::And => {
1288                        if _as.is_some() {
1289                            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.");
1290                        }
1291
1292                        let query_to_comp = format!("AND {}", haystack);
1293
1294                        match self.table.as_str() == haystack {
1295                            true => {
1296                                let mut split_the_query = self.query.split(&query_to_comp);
1297                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1298
1299                                self.query = format!("{}AND {}{}", split_the_query.nth(0).unwrap(), string_for_replace, split_the_query.nth(0).unwrap()) 
1300                            },
1301                            false => {
1302                                match self.query.matches(&query_to_comp).count() {
1303                                    0 => (),
1304                                    1 => {
1305                                        let string_for_replace = format!("AND JSON_EXTRACT({}, '${}')", haystack, needle);
1306
1307                                        self.query = self.query.replace(&query_to_comp,&string_for_replace)
1308                                    }
1309                                    _ => {
1310                                        let split_the_query = self.query.split(&query_to_comp).collect::<Vec<&str>>();
1311
1312                                        let mut last_chunk = "".to_string();
1313                                        let mut new_chunk = "".to_string();
1314                                        let length_of_split = split_the_query.len();
1315                                        
1316                                        for (index, chunk) in split_the_query.into_iter().enumerate() {
1317                                            if index + 1 == length_of_split {
1318                                                last_chunk = chunk.to_string()
1319                                            } else if index == 0 {
1320                                                new_chunk = format!("{}", chunk);
1321                                            } else {
1322                                                new_chunk = format!("{}{}{}", new_chunk, query_to_comp, chunk)
1323                                            }
1324                                        }
1325
1326                                        let string_for_replace = format!("AND JSON_EXTRACT({}, '${}')", haystack, needle);
1327
1328                                        self.query = format!("{} {} {}", new_chunk, string_for_replace, last_chunk)
1329                                    }
1330                                }
1331                            }
1332                        }
1333                    },
1334                    KeywordList::Or => {
1335                        if _as.is_some() {
1336                            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.");
1337                        }
1338
1339                        let query_to_comp = format!("OR {}", haystack);
1340
1341                        match self.table.as_str() == haystack {
1342                            true => {
1343                                let mut split_the_query = self.query.split(&query_to_comp);
1344                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1345
1346                                self.query = format!("{}OR {}{}", split_the_query.nth(0).unwrap(), string_for_replace, split_the_query.nth(0).unwrap()) 
1347                            },
1348                            false => {
1349                                match self.query.matches(&query_to_comp).count() {
1350                                    0 => (),
1351                                    1 => {
1352                                        let string_for_replace = format!("OR JSON_EXTRACT({}, '${}')", haystack, needle);
1353
1354                                        self.query = self.query.replace(&query_to_comp,&string_for_replace)
1355                                    }
1356                                    _ => {
1357                                        let split_the_query = self.query.split(&query_to_comp).collect::<Vec<&str>>();
1358
1359                                        let mut last_chunk = "".to_string();
1360                                        let mut new_chunk = "".to_string();
1361                                        let length_of_split = split_the_query.len();
1362                                        
1363                                        for (index, chunk) in split_the_query.into_iter().enumerate() {
1364                                            if index + 1 == length_of_split {
1365                                                last_chunk = chunk.to_string()
1366                                            } else if index == 0 {
1367                                                new_chunk = format!("{}", chunk);
1368                                            } else {
1369                                                new_chunk = format!("{}{}{}", new_chunk, query_to_comp, chunk)
1370                                            }
1371                                        }
1372
1373                                        let string_for_replace = format!("OR JSON_EXTRACT({}, '${}')", haystack, needle);
1374
1375                                        self.query = format!("{} {} {}", new_chunk, string_for_replace, last_chunk)
1376                                    }
1377                                }
1378                            }
1379                        }
1380                    },
1381                    KeywordList::Select => {
1382                        let string_for_put = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1383
1384                        match _as {
1385                            Some(_as) => self.query = format!("SELECT {} AS {} FROM", string_for_put, _as),
1386                            None => self.query = format!("SELECT {} FROM", string_for_put),
1387                        }
1388                    },
1389                    KeywordList::Table => {
1390                        let string_for_put = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1391
1392                        match _as {
1393                            Some(_as) => self.query = format!("SELECT {} AS {} FROM {}", string_for_put, _as, self.table),
1394                            None => self.query = format!("SELECT {} FROM {}", string_for_put, self.table),
1395                        }
1396                    },
1397                    KeywordList::OrderBy => {
1398                        if _as.is_some() {
1399                            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.");
1400                        }
1401
1402                        match self.query.matches(" ORDER BY ").count() {
1403                            0 => (),
1404                            1 => {
1405                                let split_the_query = self.query.clone();
1406                                let mut split_the_query = split_the_query.split(" ORDER BY ");
1407
1408                                let string_for_put = format!("ORDER BY JSON_EXTRACT({}, '${}')", haystack, needle);
1409        
1410                                match _as {
1411                                    Some(_as) => self.query = format!("{} {} AS {}", split_the_query.nth(0).unwrap(), string_for_put, _as),
1412                                    None => self.query = format!("{} {}", split_the_query.nth(0).unwrap(), string_for_put)
1413                                }
1414
1415                                match split_the_query.nth(0) {
1416                                    Some(comparison) => {
1417                                        match comparison.ends_with("ASC") || comparison.ends_with("asc") {
1418                                            true => self.query = format!("{} ASC", self.query),
1419                                            false => match comparison.ends_with("DESC") || comparison.ends_with("desc") {
1420                                                true => self.query = format!("{} DESC", self.query),
1421                                                false => ()
1422                                            }
1423                                        }
1424                                    },
1425                                    None => ()
1426                                }
1427                            },
1428                            _ => ()
1429                        }
1430                    },
1431                    KeywordList::Count => {
1432                        let mut split_the_query = self.query.split(" COUNT");
1433
1434                        let string_for_put = match _as {
1435                            Some(_as) => format!("JSON_EXTRACT({}, '${}') AS {}", haystack, needle, _as),
1436                            None => format!("JSON_EXTRACT({}, '${}')", haystack, needle)
1437                        };
1438
1439                        self.query = format!("SELECT {}, COUNT{}", string_for_put, split_the_query.nth(1).unwrap())
1440                    },
1441                    KeywordList::JsonExtract => {
1442                        let mut split_the_query = self.query.split(" FROM");
1443
1444                        match _as {
1445                            Some(_as) => self.query = format!("{}, JSON_EXTRACT({}, '${}') AS {} FROM", split_the_query.nth(0).unwrap(), haystack, needle, _as),
1446                            None => panic!("If you want to chain .json_extract() methods, you have to give them a tag.")
1447                        }
1448                    }
1449                    _ => ()
1450                }
1451            },
1452            None => ()
1453        }
1454        
1455        self.list.push(KeywordList::JsonExtract);
1456        self
1457    }
1458
1459    /// It applies "JSON_CONTAINS()" mysql function with it's Synthax. If you encounter any syntactic bugs or deficiencies about that function, please report it via opening an issue.
1460    /// 
1461    /// ```rust
1462    /// 
1463    /// use qubl::{QueryBuilder, ValueType, JsonValue};
1464    /// 
1465    /// fn main(){
1466    ///     let value = ValueType::String("blablabla.jpg".to_string());
1467    ///     let prop = vec![("name", &value)];
1468    /// 
1469    ///     let object = JsonValue::MysqlJsonObject(&prop);
1470    /// 
1471    ///     let query = QueryBuilder::select(["*"].to_vec()).unwrap()
1472    ///                              .table("users")
1473    ///                              .where_("pic", "=", ValueType::String("".to_string()))
1474    ///                              .json_contains("pic", object, Some(".name"))
1475    ///                              .finish();
1476    /// 
1477    ///     assert_eq!(query, "SELECT * FROM users WHERE JSON_CONTAINS(pic, JSON_OBJECT('name', 'blablabla.jpg'), '$.name');")
1478    /// }
1479    /// 
1480    /// ```
1481    pub fn json_contains(&mut self, column: &str, needle: JsonValue, path: Option<&str>) -> &mut Self {
1482        match self.list.last().unwrap() {
1483            KeywordList::Select => match path {
1484                Some(path) => match needle {
1485                    JsonValue::Initial(initial) => match initial {
1486                        ValueType::JsonString(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '\"{}\"', '${}') FROM", column, needle, path),
1487                        ValueType::String(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1488                        ValueType::Datetime(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1489                        _ => self.query = format!("SELECT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1490                    },
1491                    _ => self.query = format!("SELECT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1492                }
1493                None => match needle {
1494                    JsonValue::Initial(initial) => match initial {
1495                        ValueType::JsonString(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '\"{}\"') FROM", column, needle),
1496                        ValueType::String(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}') FROM", column, needle),
1497                        ValueType::Datetime(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}') FROM", column, needle),
1498                        _ => self.query = format!("SELECT JSON_CONTAINS({}, {}) FROM", column, needle)
1499                    },
1500                    _ => self.query = format!("SELECT JSON_CONTAINS({}, {}) FROM", column, needle)
1501                }
1502            },
1503            KeywordList::Where => match path {
1504                Some(path) => {
1505                    let mut split_the_query = self.query.split(" WHERE ");
1506
1507                    let first_half = split_the_query.nth(0);
1508
1509                    match needle {
1510                        JsonValue::Initial(initial) => match initial {
1511                            ValueType::JsonString(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '\"{}\"', '${}')", first_half.unwrap(), column, needle, path),
1512                            ValueType::String(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1513                            ValueType::Datetime(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1514                            _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1515                        },
1516                        _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1517                    }
1518                },
1519                None => {
1520                    let mut split_the_query = self.query.split(" WHERE ");
1521
1522                    let first_half = split_the_query.nth(0);
1523
1524                    match needle {
1525                        JsonValue::Initial(initial) => match initial {
1526                            ValueType::JsonString(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '\"{}\"')", first_half.unwrap(), column, needle),
1527                            ValueType::String(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1528                            ValueType::Datetime(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1529                            _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1530                        },
1531                        _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1532                    }
1533                }
1534            },
1535            KeywordList::And => match path {
1536                Some(path) => {
1537                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1538
1539                    let length_of_the_split_the_query = split_the_query.len();
1540
1541                    match split_the_query.len() {
1542                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1543                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1544                        2 => match needle {
1545                            JsonValue::Initial(initial) => match initial {
1546                                ValueType::JsonString(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1547                                ValueType::String(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1548                                ValueType::Datetime(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1549                                _ => self.query = format!("{} AND JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1550                            },
1551                            _ => self.query = format!("{} AND JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1552                        },
1553                        _ => {
1554                            let mut concatenated_string = String::new();
1555
1556                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1557                                if index == 0 {
1558                                    concatenated_string = chunk.to_string();
1559                                } else if index + 1 != length_of_the_split_the_query {
1560                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1561                                }
1562                            }
1563
1564                            match needle {
1565                                JsonValue::Initial(initial) => match initial {
1566                                    ValueType::JsonString(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1567                                    ValueType::String(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1568                                    ValueType::Datetime(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1569                                    _ => self.query = format!("{}AND JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1570                                },
1571                                _ => self.query = format!("{}AND JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1572                            }
1573                        }
1574                    }
1575                },
1576                None => {
1577                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1578
1579                    let length_of_the_split_the_query = split_the_query.len();
1580
1581                    match split_the_query.len() {
1582                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1583                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1584                        2 => match needle {
1585                            JsonValue::Initial(initial) => match initial {
1586                                ValueType::JsonString(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1587                                ValueType::String(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1588                                ValueType::Datetime(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1589                                _ => self.query = format!("{} AND JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1590                            },
1591                            _ => self.query = format!("{} AND JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1592                        },
1593                        _ => {
1594                            let mut concatenated_string = String::new();
1595
1596                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1597                                if index == 0 {
1598                                    concatenated_string = chunk.to_string();
1599                                } else if index + 1 != length_of_the_split_the_query {
1600                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1601                                }
1602                            }
1603
1604                            match needle {
1605                                JsonValue::Initial(initial) => match initial {
1606                                    ValueType::JsonString(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1607                                    ValueType::String(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1608                                    ValueType::Datetime(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1609                                    _ => self.query = format!("{}AND JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1610                                },
1611                                _ => self.query = format!("{}AND JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1612                            }
1613                        }
1614                    }
1615                }
1616            },
1617            KeywordList::Or => match path {
1618                Some(path) => {
1619                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1620
1621                    let length_of_the_split_the_query = split_the_query.len();
1622
1623                    match split_the_query.len() {
1624                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1625                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1626                        2 => match needle {
1627                            JsonValue::Initial(initial) => match initial {
1628                                ValueType::JsonString(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1629                                ValueType::String(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1630                                ValueType::Datetime(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1631                                _ => self.query = format!("{} OR JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1632                            },
1633                            _ => self.query = format!("{} OR JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1634                        },
1635                        _ => {
1636                            let mut concatenated_string = String::new();
1637
1638                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1639                                if index == 0 {
1640                                    concatenated_string = chunk.to_string();
1641                                } else if index + 1 != length_of_the_split_the_query {
1642                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1643                                }
1644                            }
1645
1646                            match needle {
1647                                JsonValue::Initial(initial) => match initial {
1648                                    ValueType::JsonString(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1649                                    ValueType::String(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1650                                    ValueType::Datetime(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1651                                    _ => self.query = format!("{}OR JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1652                                },
1653                                _ => self.query = format!("{}OR JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1654                            }
1655                        }
1656                    }
1657                },
1658                None => {
1659                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1660
1661                    let length_of_the_split_the_query = split_the_query.len();
1662
1663                    match split_the_query.len() {
1664                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1665                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1666                        2 => match needle {
1667                            JsonValue::Initial(initial) => match initial {
1668                                ValueType::JsonString(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1669                                ValueType::String(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1670                                ValueType::Datetime(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1671                                _ => self.query = format!("{} OR JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1672                            },
1673                            _ => self.query = format!("{} OR JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1674                        },
1675                        _ => {
1676                            let mut concatenated_string = String::new();
1677
1678                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1679                                if index == 0 {
1680                                    concatenated_string = chunk.to_string();
1681                                } else if index + 1 != length_of_the_split_the_query {
1682                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1683                                }
1684                            }
1685
1686                            match needle {
1687                                JsonValue::Initial(initial) => match initial {
1688                                    ValueType::JsonString(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1689                                    ValueType::String(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1690                                    ValueType::Datetime(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1691                                    _ => self.query = format!("{}OR JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1692                                },
1693                                _ => self.query = format!("{}OR JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1694                            }
1695                        }
1696                    }
1697                }
1698            },
1699            _ => panic!("Wrong usage of '.json_contains()' method, it should be used later than either SELECT, WHERE, AND, OR keywords.")
1700        }
1701
1702        self.list.push(KeywordList::JsonContains);
1703
1704        self
1705    }
1706
1707    /// It applies "NOT JSON_CONTAINS()" mysql function with it's Synthax. If you encounter any syntactic bugs or deficiencies about that function, please report it via opening an issue.
1708    /// 
1709    /// ```rust
1710    /// 
1711    /// use qubl::{QueryBuilder, ValueType, JsonValue};
1712    /// 
1713    /// fn main(){
1714    ///     let value = ValueType::String("blablabla.jpg".to_string());
1715    ///     let prop = vec![("name", &value)];
1716    /// 
1717    ///     let object = JsonValue::MysqlJsonObject(&prop);
1718    /// 
1719    ///     let query = QueryBuilder::select(["*"].to_vec()).unwrap()
1720    ///                              .table("users")
1721    ///                              .where_("pic", "=", ValueType::String("".to_string()))
1722    ///                              .not_json_contains("pic", object, Some(".name"))
1723    ///                              .finish();
1724    /// 
1725    ///     assert_eq!(query, "SELECT * FROM users WHERE NOT JSON_CONTAINS(pic, JSON_OBJECT('name', 'blablabla.jpg'), '$.name');")
1726    /// }
1727    /// 
1728    /// ```
1729    pub fn not_json_contains(&mut self, column: &str, needle: JsonValue, path: Option<&str>) -> &mut Self {
1730        match self.list.last().unwrap() {
1731            KeywordList::Select => match path {
1732                Some(path) => match needle {
1733                    JsonValue::Initial(initial) => match initial {
1734                        ValueType::JsonString(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '\"{}\"', '${}') FROM", column, needle, path),
1735                        ValueType::String(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1736                        ValueType::Datetime(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1737                        _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1738                    },
1739                    _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1740                }
1741                None => match needle {
1742                    JsonValue::Initial(initial) => match initial {
1743                        ValueType::JsonString(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '\"{}\"') FROM", column, needle),
1744                        ValueType::String(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}') FROM", column, needle),
1745                        ValueType::Datetime(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}') FROM", column, needle),
1746                        _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}) FROM", column, needle)
1747                    },
1748                    _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}) FROM", column, needle)
1749                }
1750            },
1751            KeywordList::Where => match path {
1752                Some(path) => {
1753                    let mut split_the_query = self.query.split(" WHERE ");
1754
1755                    let first_half = split_the_query.nth(0);
1756
1757                    match needle {
1758                        JsonValue::Initial(initial) => match initial {
1759                            ValueType::JsonString(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '\"{}\"', '${}')", first_half.unwrap(), column, needle, path),
1760                            ValueType::String(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1761                            ValueType::Datetime(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1762                            _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1763                        },
1764                        _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1765                    }
1766                },
1767                None => {
1768                    let mut split_the_query = self.query.split(" WHERE ");
1769
1770                    let first_half = split_the_query.nth(0);
1771
1772                    match needle {
1773                        JsonValue::Initial(initial) => match initial {
1774                            ValueType::JsonString(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '\"{}\"')", first_half.unwrap(), column, needle),
1775                            ValueType::String(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1776                            ValueType::Datetime(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1777                            _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1778                        },
1779                        _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1780                    }
1781                }
1782            },
1783            KeywordList::And => match path {
1784                Some(path) => {
1785                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1786
1787                    let length_of_the_split_the_query = split_the_query.len();
1788
1789                    match split_the_query.len() {
1790                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1791                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1792                        2 => match needle {
1793                            JsonValue::Initial(initial) => match initial {
1794                                ValueType::JsonString(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1795                                ValueType::String(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1796                                ValueType::Datetime(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1797                                _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1798                            },
1799                            _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1800                        },
1801                        _ => {
1802                            let mut concatenated_string = String::new();
1803
1804                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1805                                if index == 0 {
1806                                    concatenated_string = chunk.to_string();
1807                                } else if index + 1 != length_of_the_split_the_query {
1808                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1809                                }
1810                            }
1811
1812                            match needle {
1813                                JsonValue::Initial(initial) => match initial {
1814                                    ValueType::JsonString(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1815                                    ValueType::String(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1816                                    ValueType::Datetime(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1817                                    _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1818                                },
1819                                _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1820                            }
1821                        }
1822                    }
1823                },
1824                None => {
1825                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1826
1827                    let length_of_the_split_the_query = split_the_query.len();
1828
1829                    match split_the_query.len() {
1830                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1831                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1832                        2 => match needle {
1833                            JsonValue::Initial(initial) => match initial {
1834                                ValueType::JsonString(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1835                                ValueType::String(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1836                                ValueType::Datetime(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1837                                _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1838                            },
1839                            _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1840                        },
1841                        _ => {
1842                            let mut concatenated_string = String::new();
1843
1844                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1845                                if index == 0 {
1846                                    concatenated_string = chunk.to_string();
1847                                } else if index + 1 != length_of_the_split_the_query {
1848                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1849                                }
1850                            }
1851
1852                            match needle {
1853                                JsonValue::Initial(initial) => match initial {
1854                                    ValueType::JsonString(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1855                                    ValueType::String(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1856                                    ValueType::Datetime(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1857                                    _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1858                                },
1859                                _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1860                            }
1861                        }
1862                    }
1863                }
1864            },
1865            KeywordList::Or => match path {
1866                Some(path) => {
1867                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1868
1869                    let length_of_the_split_the_query = split_the_query.len();
1870
1871                    match split_the_query.len() {
1872                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1873                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1874                        2 => match needle {
1875                            JsonValue::Initial(initial) => match initial {
1876                                ValueType::JsonString(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1877                                ValueType::String(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1878                                ValueType::Datetime(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1879                                _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1880                            },
1881                            _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1882                        },
1883                        _ => {
1884                            let mut concatenated_string = String::new();
1885
1886                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1887                                if index == 0 {
1888                                    concatenated_string = chunk.to_string();
1889                                } else if index + 1 != length_of_the_split_the_query {
1890                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1891                                }
1892                            }
1893
1894                            match needle {
1895                                JsonValue::Initial(initial) => match initial {
1896                                    ValueType::JsonString(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1897                                    ValueType::String(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1898                                    ValueType::Datetime(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1899                                    _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1900                                },
1901                                _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1902                            }
1903                        }
1904                    }
1905                },
1906                None => {
1907                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1908
1909                    let length_of_the_split_the_query = split_the_query.len();
1910
1911                    match split_the_query.len() {
1912                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1913                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1914                        2 => match needle {
1915                            JsonValue::Initial(initial) => match initial {
1916                                ValueType::JsonString(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1917                                ValueType::String(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1918                                ValueType::Datetime(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1919                                _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1920                            },
1921                            _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1922                        },
1923                        _ => {
1924                            let mut concatenated_string = String::new();
1925
1926                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1927                                if index == 0 {
1928                                    concatenated_string = chunk.to_string();
1929                                } else if index + 1 != length_of_the_split_the_query {
1930                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1931                                }
1932                            }
1933
1934                            match needle {
1935                                JsonValue::Initial(initial) => match initial {
1936                                    ValueType::JsonString(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1937                                    ValueType::String(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1938                                    ValueType::Datetime(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1939                                    _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1940                                },
1941                                _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1942                            }
1943                        }
1944                    }
1945                }
1946            },
1947            _ => panic!("Wrong usage of '.not_json_contains()' method, it should be used later than either SELECT, WHERE, AND, OR keywords.")
1948        }
1949
1950        self.list.push(KeywordList::NotJsonContains);
1951
1952        self
1953    }
1954
1955    /// it adds `JSON_ARRAY_APPEND()` mysql function with it's synthax. It's intended to used with only update constructor, don't use it with any other kind of query.
1956    /// 
1957    /// ```rust
1958    /// 
1959    /// use qubl::{QueryBuilder, ValueType, JsonValue};
1960    /// 
1961    /// fn main () {
1962    ///     let lesson = ("lesson", &ValueType::String("math".to_string()));
1963    ///     let point = ("point", &ValueType::Int32(100));
1964    ///
1965    ///     let values = vec![lesson, point];
1966    ///
1967    ///     let object = JsonValue::MysqlJsonObject(&values);
1968    ///
1969    ///     let query = QueryBuilder::update().unwrap()
1970    ///                                 .table("users")
1971    ///                                 .json_array_append("points", Some(""), object.clone())
1972    ///                                 .where_("id", "=", ValueType::Int8(1))
1973    ///                                 .finish();
1974    ///
1975    ///     assert_eq!("UPDATE users SET points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
1976    /// }
1977    /// 
1978    /// ```
1979    pub fn json_array_append(&mut self, column: &str, path: Option<&str>, object: JsonValue) -> &mut Self {
1980        match self.list.last() {
1981            Some(keyword) => match keyword {
1982                KeywordList::Set => {
1983                    match path {
1984                        Some(path) => match object {
1985                            JsonValue::Initial(initial) => match initial {
1986                                ValueType::JsonString(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '\"{}\"')", self.query, column, column, path, object),
1987                                ValueType::String(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
1988                                ValueType::Datetime(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
1989                                _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
1990                            },
1991                            _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
1992                        }
1993                        None => match object {
1994                            JsonValue::Initial(initial) => match initial {
1995                                ValueType::JsonString(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '\"{}\"')", self.query, column, column, object),
1996                                ValueType::String(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
1997                                ValueType::Datetime(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
1998                                _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
1999                            },
2000                            _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2001                        }
2002                    }
2003                },
2004                _ => {
2005                    match path {
2006                        Some(path) => match object {
2007                            JsonValue::Initial(initial) => match initial {
2008                                ValueType::JsonString(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '\"{}\"')", self.query, column, column, path, object),
2009                                ValueType::String(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
2010                                ValueType::Datetime(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
2011                                _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
2012                            },
2013                            _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
2014                        }
2015                        None => match object {
2016                            JsonValue::Initial(initial) => match initial {
2017                                ValueType::JsonString(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '\"{}\"')", self.query, column, column, object),
2018                                ValueType::String(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
2019                                ValueType::Datetime(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
2020                                _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2021                            },
2022                            _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2023                        }
2024                    }
2025                }
2026            },
2027            None => panic!("it's impossible to came here!")
2028        }
2029
2030        self.list.push(KeywordList::JsonArrayAppend);
2031        self
2032    }
2033
2034    /// it adds "JSON_REMOVE()" function with it's synthax. You cannot pass empty strings to paths.
2035    /// 
2036    /// ```rust
2037    /// 
2038    /// use qubl::{QueryBuilder, ValueType};
2039    /// 
2040    /// fn main () {
2041    ///   let query = QueryBuilder::update().unwrap()
2042    ///                            .table("blogs")
2043    ///                            .json_remove("likes", vec!["[10]"])
2044    ///                            .where_("blog_id", "=", ValueType::Int32(20))
2045    ///                            .finish();
2046    ///
2047    ///   assert_eq!(query, "UPDATE blogs SET likes = JSON_REMOVE(likes, '$[10]') WHERE blog_id = 20;");
2048    /// }
2049    /// 
2050    /// ```
2051    pub fn json_remove(&mut self, column: &str, paths: Vec<&str>) -> &mut Self {
2052        match paths.iter().any(|path| *path == "") {
2053            true => panic!("Error: a value in the paths cannot be empty string, panicking..."),
2054            false => ()
2055        }
2056
2057        match self.list.last() {
2058            Some(keyword) => match keyword {
2059                KeywordList::Set => {
2060                    self.query = format!("{}, {} = JSON_REMOVE({}", self.query, column, column);
2061
2062                    for path in paths {
2063                        if path.starts_with("$") {
2064                            self.query = format!("{}, '${}'", self.query, path.replace("$", ""))
2065                        } else {
2066                            self.query = format!("{}, '${}'", self.query, path)
2067                        }
2068                    }
2069
2070                    self.query = format!("{})", self.query)
2071                },
2072                _ => {
2073                    self.query = format!("{} SET {} = JSON_REMOVE({}", self.query, column, column);
2074
2075                    for path in paths {
2076                        if path.starts_with("$") {
2077                            self.query = format!("{}, '${}'", self.query, path.replace("$", ""))
2078                        } else {
2079                            self.query = format!("{}, '${}'", self.query, path)
2080                        }
2081                    }
2082
2083                    self.query = format!("{})", self.query)
2084                }
2085            },
2086            None => panic!("it's impossible to came here!")
2087        }
2088
2089        self.list.push(KeywordList::JsonRemove);
2090        self
2091    }
2092
2093    /// It adds `JSON_SET()` function with it's synthax. It updates values with the specified path.
2094    /// 
2095    /// ```rust
2096    /// 
2097    /// use qubl::{QueryBuilder, ValueType, JsonValue};
2098    /// 
2099    /// fn main () {
2100    /// 
2101    /// let lesson = ("lesson", &ValueType::String("math".to_string()));
2102    /// let point = ("point", &ValueType::Int32(100));
2103    ///
2104    /// let values = vec![lesson, point];
2105    ///
2106    /// let object = JsonValue::MysqlJsonObject(&values);
2107    ///
2108    /// let query = QueryBuilder::update().unwrap()
2109    ///                          .table("users")
2110    ///                          .json_set("points", "[0]", object)
2111    ///                          .where_("id", "=", ValueType::Int32(1))
2112    ///                          .finish();
2113    ///
2114    /// assert_eq!("UPDATE users SET points = JSON_SET(points, '$[0]', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
2115    /// 
2116    /// }
2117    /// 
2118    /// ```
2119    pub fn json_set(&mut self, column: &str, path: &str, value: JsonValue) -> &mut Self {
2120        match self.list.last() {
2121            Some(keyword) => match keyword {
2122                KeywordList::Set => match value {
2123                    JsonValue::Initial(initial) => match initial {
2124                        ValueType::JsonString(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2125                        ValueType::String(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2126                        ValueType::Datetime(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2127                        _ => self.query = format!("{}, {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value),
2128                    },
2129                    _ => self.query = format!("{}, {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value),
2130                }
2131                _ => match value {
2132                    JsonValue::Initial(initial) => match initial {
2133                        ValueType::JsonString(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2134                        ValueType::String(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2135                        ValueType::Datetime(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2136                        _ => self.query = format!("{} SET {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value)
2137                    },
2138                    _ => self.query = format!("{} SET {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value)
2139                }
2140            },
2141            None => panic!("it's impossible to came here!")
2142        }
2143
2144        self.list.push(KeywordList::JsonSet);
2145        self
2146    }
2147
2148    /// It adds `JSON_REPLACE()` function with it's synthax. It updates values with the specified path.
2149    /// 
2150    /// ```rust
2151    /// 
2152    /// use qubl::{QueryBuilder, ValueType, JsonValue};
2153    /// 
2154    /// fn main () {
2155    /// 
2156    /// let value = ValueType::Int32(100);
2157    /// let value = JsonValue::Initial(&value);
2158    ///
2159    /// let query = QueryBuilder::update().unwrap()
2160    ///                          .table("users")
2161    ///                          .json_replace("points", "[0].point", value)
2162    ///                          .where_("id", "=", ValueType::Int32(1))
2163    ///                          .finish();
2164    ///
2165    /// assert_eq!("UPDATE users SET points = JSON_REPLACE(points, '$[0].point', 100) WHERE id = 1;", query)
2166    /// 
2167    /// }
2168    /// 
2169    /// ```
2170    pub fn json_replace(&mut self, column: &str, path: &str, value: JsonValue) -> &mut Self {
2171        match self.list.last() {
2172            Some(keyword) => match keyword {
2173                KeywordList::Set => match value {
2174                    JsonValue::Initial(initial) => match initial {
2175                        ValueType::JsonString(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2176                        ValueType::String(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2177                        ValueType::Datetime(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2178                        _ => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value),
2179                    },
2180                    _ => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value),
2181                }
2182                _ => match value {
2183                    JsonValue::Initial(initial) => match initial {
2184                        ValueType::JsonString(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2185                        ValueType::String(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2186                        ValueType::Datetime(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2187                        _ => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value)
2188                    },
2189                    _ => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value)
2190                }
2191            },
2192            None => panic!("it's impossible to came here!")
2193        }
2194
2195        self.list.push(KeywordList::JsonSet);
2196        self
2197    }
2198
2199    /// finishes the query and returns the result as string.
2200    pub fn finish(&self) -> String {
2201        return format!("{};", self.query);
2202    }
2203
2204    /// gives you an immutable copy of that instance, just for case if you need to share and potentially mutate it across threads.
2205    pub fn copy(&mut self) -> Self {
2206        Self {
2207            query: self.query.clone(),
2208            table: self.table.clone(),
2209            qtype: self.qtype.clone(),
2210            list: self.list.clone(),
2211            hq: self.hq
2212        }
2213    }
2214
2215    fn load_hqs() -> [&'a str; 26] {
2216        [";", "; drop", "admin' #", "admin'/*", "; union", "or 1 = 1",
2217        "or 1 = 1#", "or 1 = 1/*", "or true = true", "or false = false", "or '1' = '1'", "or '1' = '1'#",
2218        "or '1' = '1'/*", "; sleep(", "--", "drop table", "drop schema", "select if", "union select",
2219        "union all", "exec", "master..", "masters..", "information_schema", "load_file", "alter user"]
2220    }
2221
2222    fn sanitize_column(&mut self, column: &str)  -> std::result::Result<(), std::io::Error>  {
2223        match self.hq {
2224            Some(hqs) => {
2225                for _hq in hqs.iter() {
2226                    if &column == _hq {
2227                        return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2228                    }
2229                }
2230            },
2231            None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Your input is invalid."))
2232        }
2233
2234        Ok(())
2235    }
2236
2237    /// checks the inputs for potential sql injection patterns and throws error if they exist.
2238    fn sanitize_columns(columns: &Vec<&str>, hqs: [&'a str; 26]) -> std::result::Result<(), std::io::Error> {
2239        if columns.len() == 1 && columns[0] == "" {
2240            return Ok(());
2241        };
2242
2243        for column in columns.iter() {
2244            for hq in hqs.iter() {
2245                if column == hq {
2246                    return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2247                }
2248            }
2249        }
2250
2251        return Ok(())
2252    }
2253
2254    fn sanitize_inputs(inputs: &Vec<ValueType>, hqs: [&'a str; 26]) -> std::result::Result<(), std::io::Error> {
2255        for input in inputs.iter() {
2256            match input {
2257                ValueType::String(string) | ValueType::Datetime(string) => {
2258                    for hq in hqs.iter() {
2259                        if &string == hq {
2260                            return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2261                        }
2262                    }
2263                },
2264                _ => continue
2265            }
2266        }
2267
2268        return Ok(())
2269    }
2270
2271    fn sanitize_input(&mut self, input: &ValueType) -> std::result::Result<(), std::io::Error> {
2272        match input {
2273            ValueType::String(string) | ValueType::Datetime(string) => {
2274                match self.hq {
2275                    Some(hqs) => {
2276                        for hq in hqs.iter() {
2277                            if &string == hq {
2278                                return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2279                            }
2280                        }
2281                    },
2282                    None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Your input is invalid."))
2283                }
2284            },
2285            _ => return Ok(())
2286        };
2287
2288        Ok(())
2289    }
2290
2291    fn sanitize_mark(input: &str) -> std::result::Result<(), std::io::Error> {
2292        return match input {
2293            "=" | "<" | ">" | "<=" | ">=" | "!=" | "<>" => Ok(()),
2294            _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=,  >=, != or <>."))
2295        }
2296    }
2297
2298    fn sanitize_str(&mut self, input: &str) -> std::result::Result<(), std::io::Error> {
2299        match self.hq {
2300            Some(hqs) => {
2301                for hq in hqs.iter() {
2302                    if *hq == input {
2303                        return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=,  >=, != or <>."))
2304                    }
2305                }
2306            },
2307            None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=,  >=, != or <>."))
2308        }
2309
2310        Ok(())
2311    }
2312}
2313
2314/// Struct that benefits you to create and use schema's.
2315#[derive(Debug, Clone)]
2316pub struct SchemaBuilder {
2317    pub query: String,
2318    pub schema: String,
2319    pub list: Vec<KeywordList>
2320}
2321
2322/// implementations fon SchemaBuilder
2323impl SchemaBuilder {
2324    pub fn create(name: &str) -> std::result::Result<Self, std::io::Error> {
2325        if name.contains("!") ||
2326           name.contains("-") ||
2327           name.contains("=") ||
2328           name.contains("+") ||
2329           name.contains("%") ||
2330           name.contains("$") ||
2331           name.contains("&") ||
2332           name.contains("#") ||
2333           name.contains("[") ||
2334           name.contains("]") ||
2335           name.contains("{") ||
2336           name.contains("}") ||
2337           name.contains(":") ||
2338           name.contains(";") ||
2339           name.contains("'") ||
2340           name.contains("\"") ||
2341           name.contains(",") ||
2342           name.contains(".") {
2343                return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Schame name cannot include these characters: '!', '-', '=', '+', '%', '$', '&', '#', '[', ']', '{', '}', ':', ';', '\"', \"'\", '.', ','"))
2344        }
2345
2346        Ok(Self {
2347            query: format!("CREATE DATABASE {}", name),
2348            schema: name.to_string(),
2349            list: vec![KeywordList::Create]
2350        })
2351    }
2352
2353    pub fn use_another_schema(name: &str) -> std::result::Result<Self, std::io::Error> {
2354        if name.contains("!") ||
2355        name.contains("-") ||
2356        name.contains("=") ||
2357        name.contains("+") ||
2358        name.contains("%") ||
2359        name.contains("$") ||
2360        name.contains("&") ||
2361        name.contains("#") ||
2362        name.contains("[") ||
2363        name.contains("]") ||
2364        name.contains("{") ||
2365        name.contains("}") ||
2366        name.contains(":") ||
2367        name.contains(";") ||
2368        name.contains("'") ||
2369        name.contains("\"") ||
2370        name.contains(",") ||
2371        name.contains(".") {
2372             return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Schame name cannot include these characters: '!', '-', '=', '+', '%', '$', '&', '#', '[', ']', '{', '}', ':', ';', '\"', \"'\", '.', ','"))
2373        }
2374
2375        Ok(Self {
2376            query: format!("USE {}", name),
2377            schema: name.to_string(),
2378            list: vec![KeywordList::Use, KeywordList::Create]
2379        })
2380    }
2381
2382    pub fn if_not_exists(&mut self) -> &mut Self {
2383        match self.list[0] {
2384            KeywordList::Create => (),
2385            KeywordList::Table => (),
2386            _ => panic!("if_not_exists method cannot be used without Create or Table queries")
2387        }
2388
2389        let split_the_query =  self.query.split(" DATABASE ").collect::<Vec<&str>>();
2390        self.query = format!("{} DATABASE IF NOT EXISTS {}", split_the_query[0], split_the_query[1]);
2391
2392        self.list.insert(0, KeywordList::IfNotExist);
2393        self
2394    }
2395
2396    pub fn use_schema(&mut self, name: Option<&str>) -> &mut Self {
2397        match name {
2398            Some(schema_name) => {
2399                self.query = format!("USE {}", schema_name)
2400            },
2401            None => {
2402                self.query = format!("USE {}", self.schema);
2403            }
2404        }
2405
2406        self
2407    }
2408
2409    pub fn finish(&self) -> String {
2410        return format!("{};", self.query)
2411    }
2412}
2413
2414/// Struct that benefits you to create Tables. Currently incomplete thoug.
2415#[derive(Debug, Clone)]
2416pub struct TableBuilder {
2417    pub query: String,
2418    pub name: String,
2419    pub schema: String,
2420    pub all: Vec<String>,
2421}
2422
2423/// Struct that benefits to define a foreign key.
2424#[derive(Debug, Clone)]
2425pub struct ForeignKey {
2426    pub first: ForeignKeyItem,
2427    pub second: ForeignKeyItem,
2428    pub on_delete: Option<ForeignKeyActions>,
2429    pub on_update: Option<ForeignKeyActions>,
2430    pub constraint: Option<String>
2431}
2432
2433/// Struct that benefits you to add a foreign key item to a foreign key.
2434#[derive(Debug, Clone)]
2435pub struct ForeignKeyItem {
2436    pub table: String,
2437    pub column: String
2438}
2439
2440/// implementations for TableBuilder
2441impl TableBuilder {
2442    pub fn create(schema_name: &str, table_name: &str) -> Self {
2443        return Self {
2444            query: format!("CREATE TABLE {} (", table_name),
2445            schema: schema_name.to_string(),
2446            name: table_name.to_string(),
2447            all: vec![]
2448        }
2449    }
2450
2451    pub fn if_not_exists(&mut self) -> &mut Self {
2452        self.query = format!("{}IF NOT EXISTS (", self.query.replace("(", ""));
2453
2454        self
2455    }
2456
2457    pub fn add_column(&mut self, column_name: &str) -> &mut Self {
2458        if self.query.ends_with("(") {
2459            self.query = format!("{}{}", self.query, column_name)
2460        } else {
2461            self.query = format!("{}, {}", self.query, column_name)
2462        }
2463
2464        self
2465    }
2466
2467    pub fn col_type(&mut self, type_name: &str) -> &mut Self {
2468        if self.query.ends_with("(") {
2469            panic!("Cannot add type before defining a column name.")
2470        }
2471
2472        self.query = format!("{} {}", self.query, type_name);
2473
2474        self
2475    }
2476
2477    pub fn null(&mut self) -> &mut Self {
2478        self.query = format!("{} NULL", self.query);
2479
2480        self
2481    }
2482
2483    pub fn not_null(&mut self) -> &mut Self {
2484        self.query = format!("{} NOT NULL", self.query);
2485
2486        self
2487    }
2488
2489    pub fn auto_increment(&mut self) -> &mut Self {
2490        self.query = format!("{} AUTO_INCREMENT", self.query);
2491
2492        self
2493    }
2494
2495    pub fn primary_key(&mut self) -> &mut Self {
2496        if self.query.contains("PRIMARY KEY") {
2497            panic!("A table cannot have two primary keys.")
2498        }
2499
2500        self.query = format!("{} PRIMARY KEY", self.query);
2501
2502        self
2503    }
2504
2505    pub fn default(&mut self, value: ValueType) -> &mut Self {
2506        let split_the_query = self.query.clone();
2507        let split_the_query = split_the_query.split(", ").collect::<Vec<&str>>();
2508
2509        let last_query = split_the_query[split_the_query.len() - 1];
2510
2511        if last_query.contains("INT") || 
2512           last_query.contains("TINYINT") ||
2513           last_query.contains("SMALLINT") ||
2514           last_query.contains("MEDIUMINT") ||
2515           last_query.contains("BIGINT") ||
2516           last_query.contains("BIT") ||
2517           last_query.contains("SERIAL") {
2518            match value {
2519                ValueType::Int8(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2520                ValueType::Int16(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2521                ValueType::Int32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2522                ValueType::Int64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2523                ValueType::Uint8(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2524                ValueType::Uint16(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2525                ValueType::Uint32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2526                ValueType::Uint64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2527                ValueType::Usize(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2528                ValueType::Float32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2529                ValueType::Float64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2530                _ => 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.")
2531            }
2532        }
2533
2534        if last_query.contains("BOOL") || 
2535           last_query.contains("BOOLEAN") {
2536            match value {
2537                ValueType::Boolean(boolean) => self.query = format!("{} DEFAULT {}", self.query, boolean),
2538                _ => panic!("If your column type is BOOLEAN, you have to write either true or false.")
2539            }    
2540        }
2541
2542        if last_query.contains("CHAR") ||
2543           last_query.contains("VARCHAR") ||
2544           last_query.contains("TEXT") ||
2545           last_query.contains("TINYTEXT") ||
2546           last_query.contains("MEDIUMTEXT") ||
2547           last_query.contains("LONGTEXT") ||
2548           last_query.contains("BINARY") ||
2549           last_query.contains("VARBINARY") {
2550            match value {
2551                ValueType::String(ref text) => self.query = format!("{} DEFAULT '{}'", self.query, text),
2552                _ => 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.")
2553            }
2554        }
2555
2556        if last_query.contains("DATETIME") ||
2557           last_query.contains("TIMESTAMP") {
2558            match value {
2559                ValueType::Datetime(datetime) => self.query = format!("{} DEFAULT {}", self.query, datetime),
2560                _ => 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.")
2561            }
2562        }
2563
2564        self
2565    }
2566
2567    pub fn unique(&mut self) -> &mut Self {
2568        self.query = format!("{} UNIQUE", self.query);
2569
2570        self
2571    }
2572
2573    pub fn check(&mut self, condition: &str) -> &mut Self {
2574        self.query = format!("{} CHECK({})", self.query, condition);
2575
2576        self
2577    }
2578
2579    pub fn character_set(&mut self, character_set: &str) -> &mut Self {
2580        self.query = format!("{} CHARACTER SET {}", self.query, character_set);
2581
2582        self
2583    }
2584
2585    pub fn foreign_key(&mut self, opts: ForeignKey) -> &mut Self {
2586        if self.query.starts_with("ALTER TABLE") {
2587            match opts.constraint {
2588                Some(constraint) => self.query = format!("{}, ADD CONSTRAINT {} FOREIGN KEY ({})", self.query, constraint, opts.first.column),
2589                None => self.query = format!("{}, ADD FOREIGN KEY ({})", self.query, opts.first.column)
2590            }
2591            
2592        } else {
2593            match opts.constraint {
2594                Some(constraint) => self.query = format!("{}, CONSTRAINT {} FOREIGN KEY ({})", self.query, constraint, opts.first.column),
2595                None => self.query = format!("{}, FOREIGN KEY ({})", self.query, opts.first.column)
2596            }
2597        }
2598
2599        self.query = format!("{} REFERENCES {}({})", self.query, opts.second.table, opts.second.column);
2600
2601        match opts.on_delete {
2602            Some(on_delete_opt) => self.query = format!("{} ON DELETE {}", self.query, on_delete_opt),
2603            None => ()
2604        }
2605
2606        match opts.on_update {
2607            Some(on_update_opt) => self.query = format!("{} ON UPDATE {}", self.query, on_update_opt),
2608            None => ()
2609        }
2610
2611        self
2612    }
2613
2614    pub fn unsigned(&mut self) -> &mut Self {
2615        self.query = format!("{} UNSIGNED", self.query);
2616
2617        self
2618    }
2619
2620    pub fn zerofill(&mut self) -> &mut Self {
2621        self.query = format!("{} ZEROFILL", self.query);
2622
2623        self
2624    }
2625
2626    pub fn enum_sql(&mut self, enum_vec: Vec<&str>) -> &mut Self {
2627        match enum_vec.len() {
2628            0 => panic!("enum_vec argument cannot be an empty vector"),
2629            _ => ()
2630        }
2631        
2632        self.query = format!("{} ENUM(", self.query);
2633
2634        let length_of_enum_vec = enum_vec.len();
2635        for (index, item) in enum_vec.into_iter().enumerate() {
2636            if index + 1 == length_of_enum_vec {
2637                self.query = format!("{}'{}'", self.query, item)
2638            } else {
2639                self.query = format!("{}'{}', ", self.query, item)
2640            }
2641        }
2642
2643        self
2644    }
2645
2646    pub fn generated_always(&mut self, condition: &str) -> &mut Self {
2647        self.query = format!("{} GENERATED ALWAYS AS {}", self.query, condition);
2648
2649        self
2650    }
2651
2652    pub fn virtual_sql(&mut self) -> &mut Self {
2653        self.query = format!("{} VIRTUAL", self.query);
2654
2655        self
2656    }
2657
2658    pub fn stored(&mut self) -> &mut Self {
2659        self.query = format!("{} STORED", self.query);
2660
2661        self
2662    }
2663
2664    pub fn spatial(&mut self) -> &mut Self {
2665        self.query = format!("{} SPATIAL", self.query);
2666
2667        self
2668    }
2669
2670    pub fn generated(&mut self) -> &mut Self {
2671        self.query = format!("{} GENERATED", self.query);
2672
2673        self
2674    }
2675
2676    pub fn index(&mut self, indexes: Vec<&str>) -> &mut Self {
2677        let length_of_indexes = indexes.len();
2678
2679        match length_of_indexes {
2680            0 => panic!("There is no index here."),
2681            1 => self.query = format!("{}, INDEX({})", self.query, indexes[0]),
2682            _ => {
2683                for (i, index) in indexes.into_iter().enumerate() {
2684                    if i + 1 == length_of_indexes {
2685                        self.query = format!("{}{}", self.query, index);
2686
2687                        continue;
2688                    }
2689
2690                    if i == 0 {
2691                        self.query = format!("{}, INDEX ({}, ", self.query, index);
2692
2693                        continue;
2694                    }
2695
2696                    self.query = format!("{}{}, ", self.query, index)
2697                }
2698            }
2699        }
2700
2701        self
2702    }
2703
2704    pub fn comment(&mut self, comment: &str) -> &mut Self {
2705        self.query = format!("{} COMMENT '{}'", self.query, comment);
2706
2707        self
2708    }
2709
2710    pub fn default_on_null(&mut self, value: ValueType) -> &mut Self {
2711        match value {
2712            ValueType::String(text) => self.query = format!("{} DEFAULT {} ON NULL", self.query, text),
2713            _ => self.query = format!("{} DEFAULT {} ON NULL", self.query, value),
2714        }
2715
2716        self
2717    }
2718
2719    pub fn invisible(&mut self) -> &mut Self {
2720        self.query = format!("{} INVISIBLE", self.query);
2721
2722        self
2723    }
2724
2725    pub fn custom_query(&mut self, query: &str) -> &mut Self {
2726        self.query = format!("{} {}", self.query, query);
2727
2728        self
2729    }
2730
2731    pub fn finish(&mut self) -> String {
2732        return format!("{});", self.query)
2733    }
2734}
2735
2736/// KeywordList enum. It helps to syntactically correcting the queries. 
2737#[derive(Debug, Clone, PartialEq)]
2738pub enum KeywordList {
2739    Select, Update, Delete, Insert, Count, Table, Where, Or, And, Set, 
2740    Finish, OrderBy, GroupBy, Having, Like, Limit, Offset, IfNotExist, Create, Use, WhereIn, 
2741    WhereNotIn, AndIn, AndNotIn, OrIn, OrNotIn, JsonExtract, JsonContains, NotJsonContains, JsonArrayAppend, JsonRemove, JsonSet, JsonReplace, 
2742    Field, Union, UnionAll, Timezone, GlobalTimezone
2743}
2744
2745/// QueryType enum. It helps to detect the type of a query with more optimized way when is needed.
2746#[derive(Debug, Clone)]
2747pub enum QueryType {
2748    Select, Update, Delete, Insert, Null, Create, Count
2749}
2750
2751/// ValueType enum. It benefits to detect and format the value with optimized way when you have to work with exact column values. 
2752#[derive(Debug, Clone)]
2753pub enum ValueType {
2754    String(String), Datetime(String), Null, Boolean(bool), Int32(i32), Int16(i16), Int8(i8), Int64(i64), Int128(i128),
2755    Uint8(u8), Uint16(u16), Uint32(u32), Uint64(u64), Usize(usize), Float32(f32), Float64(f64),
2756    EpochTime(i64), JsonString(String)
2757}
2758
2759impl std::fmt::Display for ValueType {
2760    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2761        match self {
2762            ValueType::String(string) => write!(f, "'{}'", string),
2763            ValueType::JsonString(string) => write!(f, "\"{}\"", string),
2764            ValueType::Datetime(datetime) => match datetime.as_str() {
2765                "CURRENT_TIMESTAMP" | "UNIX_TIMESTAMP" | "CURRENT_DATE" | "CURRENT_TIME" | "NOW()" | "CURDATE()" | "CURTIME()" => write!(f, "{}", datetime),
2766                _ => write!(f, "'{}'", datetime)
2767            },
2768            ValueType::Null => write!(f, "NULL"),
2769            ValueType::Boolean(val) => write!(f, "{}", val),
2770            ValueType::Int8(val) => write!(f, "{}", val),
2771            ValueType::Int16(val) => write!(f, "{}", val),
2772            ValueType::Int32(val) => write!(f, "{}", val),
2773            ValueType::Int64(val) => write!(f, "{}", val),
2774            ValueType::Int128(val) => write!(f, "{}", val),
2775            ValueType::Usize(val) => write!(f, "{}", val),
2776            ValueType::Uint8(val) => write!(f, "{}", val),
2777            ValueType::Uint16(val) => write!(f, "{}", val),
2778            ValueType::Uint32(val) => write!(f, "{}", val),
2779            ValueType::Uint64(val) => write!(f, "{}", val),
2780            ValueType::Float32(val) => write!(f, "{}", val),
2781            ValueType::Float64(val) => write!(f, "{}", val),
2782            ValueType::EpochTime(val) => write!(f, "FROM_UNIXTIME({})", val),
2783        }
2784    }
2785}
2786
2787impl From<String> for ValueType { fn from(value: String) -> Self { ValueType::String(value) } }
2788impl From<bool> for ValueType { fn from(value: bool) -> Self { ValueType::Boolean(value) } }
2789impl From<i8> for ValueType { fn from(value: i8) -> Self { ValueType::Int8(value) } }
2790impl From<i16> for ValueType { fn from(value: i16) -> Self { ValueType::Int16(value) } }
2791impl From<i32> for ValueType { fn from(value: i32) -> Self { ValueType::Int32(value) } }
2792impl From<i64> for ValueType { fn from(value: i64) -> Self { ValueType::Int64(value) } }
2793impl From<i128> for ValueType { fn from(value: i128) -> Self { ValueType::Int128(value) } }
2794impl From<usize> for ValueType { fn from(value: usize) -> Self { ValueType::Usize(value) } }
2795impl From<u8> for ValueType { fn from(value: u8) -> Self { ValueType::Uint8(value) } }
2796impl From<u16> for ValueType { fn from(value: u16) -> Self { ValueType::Uint16(value) } }
2797impl From<u32> for ValueType { fn from(value: u32) -> Self { ValueType::Uint32(value) } }
2798impl From<u64> for ValueType { fn from(value: u64) -> Self { ValueType::Uint64(value) } }
2799impl From<f32> for ValueType { fn from(value: f32) -> Self { ValueType::Float32(value) } }
2800impl From<f64> for ValueType { fn from(value: f64) -> Self { ValueType::Float64(value) } }
2801
2802
2803impl Into<String> for ValueType {
2804    fn into(self) -> String {
2805        match self {
2806            ValueType::String(text) => text,
2807            ValueType::Datetime(datetime) => datetime,
2808            _ => panic!("you cannot convert a ValueType to string unless it's not a String or Datetime variant.")
2809        }
2810    }
2811}
2812
2813impl Into<bool> for ValueType {
2814    fn into(self) -> bool {
2815        match self {
2816            ValueType::Boolean(val) => val,
2817            ValueType::String(text) => match text.as_str() {
2818                "false" | "" | "\0" | "0" => false,
2819                _ => true,
2820            }
2821            ValueType::Null => false,
2822            ValueType::Int8(val) => match val == 0 {
2823                false => true,
2824                true => false
2825            },
2826            ValueType::Int16(val) => match val == 0 {
2827                false => true,
2828                true => false
2829            },
2830            ValueType::Int32(val) => match val == 0 {
2831                false => true,
2832                true => false
2833            },
2834            ValueType::Int64(val) => match val == 0 {
2835                false => true,
2836                true => false
2837            },
2838            ValueType::Int128(val) => match val == 0 {
2839                false => true,
2840                true => false
2841            },
2842            ValueType::Uint8(val) => match val == 0 {
2843                false => true,
2844                true => false
2845            },
2846            ValueType::Uint16(val) => match val == 0 {
2847                false => true,
2848                true => false
2849            },
2850            ValueType::Uint32(val) => match val == 0 {
2851                false => true,
2852                true => false
2853            },
2854            ValueType::Uint64(val) => match val == 0 {
2855                false => true,
2856                true => false
2857            },
2858            ValueType::Float32(val) => match val == 0.0 {
2859                false => true,
2860                true => false
2861            },
2862            ValueType::Float64(val) => match val == 0.0 {
2863                false => true,
2864                true => false
2865            },
2866            _ => panic!("invalid conversion")
2867        }
2868    }
2869}
2870
2871impl Into<f32> for ValueType {
2872    fn into(self) -> f32 {
2873        match self {
2874            ValueType::Float32(num) => num,
2875            ValueType::Float64(num) => num as f32,
2876            _ => panic!("invalid conversion")
2877        }
2878    }
2879}
2880
2881impl Into<f64> for ValueType {
2882    fn into(self) -> f64 {
2883        match self {
2884            ValueType::Float32(num) => num as f64,
2885            ValueType::Float64(num) => num,
2886            _ => panic!("invalid conversion")
2887        }
2888    }
2889}
2890
2891impl Into<i8> for ValueType {
2892    fn into(self) -> i8 {
2893        match self {
2894            ValueType::Int8(num) => num,
2895            ValueType::Int16(num) => match num > 128 || num < -128 {
2896                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2897                false => num as i8
2898            },
2899            ValueType::Int32(num) => match num > 128 || num < -128 {
2900                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2901                false => num as i8
2902            },
2903            ValueType::Int64(num) => match num > 128 || num < -128 {
2904                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2905                false => num as i8
2906            },
2907            ValueType::Int128(num) => match num > 128 || num < -128 {
2908                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2909                false => num as i8
2910            }
2911            ValueType::Uint8(num) => match num > 128 {
2912                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2913                false => num as i8
2914            },
2915            ValueType::Uint16(num) => match num > 128 {
2916                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2917                false => num as i8
2918            },
2919            ValueType::Uint32(num) => match num > 128 {
2920                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2921                false => num as i8
2922            },
2923            ValueType::Usize(num) => match num > 128 {
2924                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2925                false => num as i8
2926            },
2927            ValueType::Uint64(num) => match num > 128 {
2928                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2929                false => num as i8
2930            },
2931            _ => panic!("you cannot convert non numeric values into numeric ones.")
2932        }
2933    }
2934}
2935
2936impl Into<i16> for ValueType {
2937    fn into(self) -> i16 {
2938        match self {
2939            ValueType::Int8(num) => num as i16,
2940            ValueType::Int16(num) => num,
2941            ValueType::Int32(num) => match num > 32_768 || num < -32_768 {
2942                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2943                false => num as i16
2944            },
2945            ValueType::Int64(num) => match num > 32_768 || num < -32_768 {
2946                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2947                false => num as i16
2948            },
2949            ValueType::Int128(num) => match num > 32_768 || num < -32_768 {
2950                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2951                false => num as i16
2952            }
2953            ValueType::Uint8(num) => num as i16,
2954            ValueType::Uint16(num) => match num > 32_768 {
2955                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2956                false => num as i16
2957            },
2958            ValueType::Uint32(num) => match num > 32_768 {
2959                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2960                false => num as i16
2961            },
2962            ValueType::Usize(num) => match num > 32_768 {
2963                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2964                false => num as i16
2965            },
2966            ValueType::Uint64(num) => match num > 32_768 {
2967                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2968                false => num as i16
2969            },
2970            _ => panic!("you cannot convert non numeric values into numeric ones.")
2971        }
2972    }
2973}
2974
2975impl Into<i32> for ValueType {
2976    fn into(self) -> i32 {
2977        match self {
2978            ValueType::Int8(num) => num as i32,
2979            ValueType::Int16(num) => num as i32,
2980            ValueType::Int32(num) => num,
2981            ValueType::Int64(num) => match num > 2_147_483_647 || num < -2_147_483_647 {
2982                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2983                false => num as i32
2984            },
2985            ValueType::Int128(num) => match num > 2_147_483_647 || num < -2_147_483_647 {
2986                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2987                false => num as i32
2988            }
2989            ValueType::Uint8(num) => num as i32,
2990            ValueType::Uint16(num) => num as i32,
2991            ValueType::Uint32(num) => match num > 2_147_483_647 {
2992                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2993                false => num as i32
2994            },
2995            ValueType::Usize(num) => match num > 2_147_483_647 {
2996                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
2997                false => num as i32
2998            },
2999            ValueType::Uint64(num) => match num > 2_147_483_647 {
3000                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
3001                false => num as i32
3002            }
3003            _ => panic!("you cannot convert non numeric values into numeric ones.")
3004        }
3005    }
3006}
3007
3008impl Into<i64> for ValueType {
3009    fn into(self) -> i64 {
3010        match self {
3011            ValueType::EpochTime(epoch) => epoch as i64,
3012            ValueType::Int8(num) => num as i64,
3013            ValueType::Int16(num) => num as i64,
3014            ValueType::Int32(num) => num as i64,
3015            ValueType::Int64(num) => num,
3016            ValueType::Usize(num) => num as i64,
3017            ValueType::Uint8(num) => num as i64,
3018            ValueType::Uint16(num) => num as i64,
3019            ValueType::Uint32(num) => num as i64,
3020            ValueType::Uint64(num) => num as i64,
3021            _ => panic!("you cannot convert non numeric values into numeric ones.")
3022        }
3023    }
3024}
3025
3026impl Into<u8> for ValueType {
3027    fn into(self) -> u8 {
3028        match self {
3029            ValueType::Uint8(num) => num,
3030            ValueType::Uint16(num) => match num > 255 {
3031                true => panic!("you cannot convert u16's if it's value is bigger than capacity of 8 bit values"),
3032                false => num as u8
3033            },
3034            ValueType::Uint32(num) => match num > 255 {
3035                true => panic!("you cannot convert u32's if it's value is bigger than capacity of 8 bit values"),
3036                false => num as u8
3037            },
3038            ValueType::Uint64(num) => match num > 255 {
3039                true => panic!("you cannot convert u64's if it's value is bigger than capacity of 8 bit values"),
3040                false => num as u8
3041            },
3042            ValueType::Usize(num) => match num > 255 {
3043                true => panic!("you cannot convert usizes if it's value is bigger than capacity of 8 bit values"),
3044                false => num as u8
3045            },
3046            ValueType::Int8(num) => match num < 0 {
3047                true => panic!("you cannot convert i8's if it's value is lower than 0"),
3048                false => num as u8
3049            },
3050            ValueType::Int16(num) => match num < 0 || num > 255 {
3051                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."),
3052                false => num as u8
3053            },
3054            ValueType::Int32(num) => match num < 0 || num > 255 {
3055                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."),
3056                false => num as u8
3057            },
3058            ValueType::Int64(num) => match num < 0 || num > 255 {
3059                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."),
3060                false => num as u8
3061            },
3062            ValueType::Int128(num) => match num < 0 || num > 255 {
3063                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."),
3064                false => num as u8
3065            }
3066            _ => panic!("you cannot convert non numeric values into numeric ones.")
3067        }
3068    }
3069}
3070
3071impl Into<u16> for ValueType {
3072    fn into(self) -> u16 {
3073        match self {
3074            ValueType::Uint8(num) => num as u16,
3075            ValueType::Uint16(num) => num,
3076            ValueType::Uint32(num) => match num > 65_535 {
3077                true => panic!("you cannot convert u32's if it's value is bigger than capacity of 32 bit values"),
3078                false => num as u16
3079            },
3080            ValueType::Uint64(num) => match num > 65_535 {
3081                true => panic!("you cannot convert u64's if it's value is bigger than capacity of 32 bit values"),
3082                false => num as u16
3083            },
3084            ValueType::Usize(num) => match num > 65_535 {
3085                true => panic!("you cannot convert usizes if it's value is bigger than capacity of 32 bit values"),
3086                false => num as u16
3087            },
3088            ValueType::Int8(num) => match num < 0 {
3089                true => panic!("you cannot convert i8's if it's value is lower than 0"),
3090                false => num as u16
3091            },
3092            ValueType::Int16(num) => match num < 0 {
3093                true => panic!("you cannot convert i16's if it's value is lower than 0"),
3094                false => num as u16
3095            },
3096            ValueType::Int32(num) => match num < 0 || num > 65_535 {
3097                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."),
3098                false => num as u16
3099            },
3100            ValueType::Int64(num) => match num < 0 || num > 65_535 {
3101                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."),
3102                false => num as u16
3103            },
3104            ValueType::Int128(num) => match num < 0 || num > 65_535 {
3105                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."),
3106                false => num as u16
3107            }
3108            _ => panic!("you cannot convert non numeric values into numeric ones.")
3109        }
3110    }
3111}
3112
3113impl Into<u32> for ValueType {
3114    fn into(self) -> u32 {
3115        match self {
3116            ValueType::Uint8(num) => num as u32,
3117            ValueType::Uint16(num) => num as u32,
3118            ValueType::Uint32(num) => num,
3119            ValueType::Uint64(num) => match num > 4_294_967_295 {
3120                true => panic!("you cannot convert u64's if it's value is bigger than capacity of 32 bit values"),
3121                false => num as u32
3122            },
3123            ValueType::Usize(num) => match num > 4_294_967_295 {
3124                true => panic!("you cannot convert usizes if it's value is bigger than capacity of 32 bit values"),
3125                false => num as u32
3126            },
3127            ValueType::Int8(num) => match num < 0 {
3128                true => panic!("you cannot convert i8's if it's value is lower than 0"),
3129                false => num as u32
3130            },
3131            ValueType::Int16(num) => match num < 0 {
3132                true => panic!("you cannot convert i16's if it's value is lower than 0"),
3133                false => num as u32
3134            },
3135            ValueType::Int32(num) => match num < 0 {
3136                true => panic!("you cannot convert i32's if it's value is lower than 0"),
3137                false => num as u32
3138            },
3139            ValueType::Int64(num) => match num < 0 || num > 4_294_967_295 {
3140                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."),
3141                false => num as u32
3142            },
3143            ValueType::Int128(num) => match num < 0 || num > 4_294_967_295 {
3144                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."),
3145                false => num as u32
3146            }
3147            _ => panic!("you cannot convert non numeric values into numeric ones.")
3148        }
3149    }
3150}
3151
3152impl Into<u64> for ValueType {
3153    fn into(self) -> u64 {
3154        match self {
3155            ValueType::Usize(num) => num as u64,
3156            ValueType::Uint8(num) => num as u64,
3157            ValueType::Uint16(num) => num as u64,
3158            ValueType::Uint32(num) => num as u64,
3159            ValueType::Uint64(num) => num,
3160            ValueType::Int8(num) => match num < 0 {
3161                true => panic!("you cannot turn a negative value into u64"),
3162                false => num as u64
3163            },
3164            ValueType::Int16(num) => match num < 0 {
3165                true => panic!("you cannot turn a negative value into u64"),
3166                false => num as u64
3167            },
3168            ValueType::Int32(num) => match num < 0 {
3169                true => panic!("you cannot turn a negative value into u64"),
3170                false => num as u64
3171            },
3172            ValueType::Int64(num) => match num < 0 {
3173                true => panic!("you cannot turn a negative value into u64"),
3174                false => num as u64
3175            },
3176            ValueType::Int128(num) => match num < 0 {
3177                true => panic!("you cannot turn a negative value into u64"),
3178                false => num as u64
3179            },
3180            _ => panic!("you cannot convert non numeric values into numeric ones.")
3181        }
3182    }
3183}
3184
3185impl Into<usize> for ValueType {
3186    fn into(self) -> usize {
3187        match self {
3188            ValueType::Int8(num) => match num < 0 {
3189                true => panic!("you cannot convert negative numbers to usize"),
3190                false => num as usize
3191            },
3192            ValueType::Int16(num) => match num < 0 {
3193                true => panic!("you cannot convert negative numbers to usize"),
3194                false => num as usize
3195            },
3196            ValueType::Int32(num) => match num < 0 {
3197                true => panic!("you cannot convert negative numbers to usize"),
3198                false => num as usize
3199            },
3200            ValueType::Int64(num) => match num < 0 {
3201                true => panic!("you cannot convert negative numbers to usize"),
3202                false => num as usize
3203            },
3204            ValueType::Int128(num) => match num < 0 {
3205                true => panic!("you cannot convert negative numbers to usize"),
3206                false => num as usize
3207            },
3208            ValueType::Usize(num) => num,
3209            ValueType::Uint8(num) => num as usize,
3210            ValueType::Uint16(num) => num as usize,
3211            ValueType::Uint32(num) => num as usize,
3212            ValueType::Uint64(num) => num as usize,
3213            _ => panic!("you cannot convert non numeric values into numeric ones.")
3214        }
3215    }
3216}
3217
3218/// Enum that benefits you to add json values to structs. They can be used with json functions.
3219/// That variants represents that kind of json values:
3220#[derive(Debug, Clone)]
3221pub enum JsonValue<'a> {
3222    /// 
3223    /// Example Value: ["hello", 21, "again"]
3224    /// 
3225    Array(&'a Vec<ValueType>), 
3226    
3227    /// 
3228    /// Example Value: {"name": "necdet", "message": "hello", "id": 1}
3229    /// 
3230    Object(&'a Vec<(&'a str, &'a ValueType)>), 
3231    
3232    ///
3233    /// example value: [{"name": "necdet", "message": "hello", "id": 1}, {"name": "kemal", "message": "hi", "id": 2}]
3234    /// 
3235    ObjectArray(&'a Vec<Vec<(&'a str, &'a ValueType)>>), 
3236    
3237    /// It's same with `ValueType` enums, just for simply passing it to that enum.
3238    Initial(&'a ValueType), 
3239
3240    /// Mysql Json Object: It writes JSON_OBJECT() mysql function with it's synthax, such as: JSON_OBJECT('name', 'necdet', 'message', 'hello', 'id', 13). It's necessary or more accurate when working most of the json functions.
3241    MysqlJsonObject(&'a Vec<(&'a str, &'a ValueType)>)
3242}
3243
3244impl <'a>std::fmt::Display for JsonValue<'a> {
3245    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3246        match self {
3247            JsonValue::Array(values) => {
3248                let mut json_str = "[".to_string();
3249
3250                for (index, value) in values.iter().enumerate() {
3251                    if index == 0 {
3252                        json_str = format!("{}{}", json_str, value)
3253                    } else {
3254                        json_str = format!("{}, {}", json_str, value)
3255                    }
3256                }
3257
3258                json_str = format!("{}]", json_str);
3259
3260                write!(f, "{}", json_str)
3261            },
3262            JsonValue::Object(props) => {
3263                let mut json_str = "{".to_string();
3264
3265                for (index, value) in props.iter().enumerate() {
3266                    if index == 0 {
3267                        json_str = format!("{}\"{}\": {}", json_str, value.0, value.1)
3268                    } else {
3269                        json_str = format!("{}, \"{}\": {}", json_str, value.0, value.1)
3270                    }
3271                }
3272
3273                json_str = format!("{}}}", json_str);
3274
3275                write!(f, "{}", json_str)
3276            },
3277            JsonValue::MysqlJsonObject(props) => {
3278                let mut json_str = "JSON_OBJECT(".to_string();
3279
3280                for (index, value) in props.iter().enumerate() {
3281                    if index == 0 {
3282                        json_str = format!("{}'{}', {}", json_str, value.0, value.1)
3283                    } else {
3284                        json_str = format!("{}, '{}', {}", json_str, value.0, value.1)
3285                    }
3286                }
3287
3288                json_str = format!("{})", json_str);
3289
3290                write!(f, "{}", json_str)
3291            },
3292            JsonValue::ObjectArray(array) => {
3293                let mut json_str = "[".to_string();
3294
3295                for (index1, object) in array.into_iter().enumerate() {
3296                    let mut object_str = "{".to_string();
3297
3298                    for (index2, property) in object.into_iter().enumerate() {
3299                        if index2 == 0 {
3300                            object_str = format!("{}\"{}\": {}", object_str, property.0, property.1)
3301                        } else {
3302                            object_str = format!("{}, \"{}\": {}", object_str, property.0, property.1)
3303                        }
3304                    }
3305
3306                    object_str = format!("{}}}", object_str);
3307
3308                    if index1 == 0 {
3309                        json_str = format!("{}{}", json_str, object_str)
3310                    } else {
3311                        json_str = format!("{}, {}", json_str, object_str)
3312                    }
3313                }
3314
3315                write!(f, "{}]", json_str)
3316            },
3317            JsonValue::Initial(value) => write!(f, "{}", value.to_string())
3318        }
3319    }
3320}
3321
3322#[derive(Debug, Clone)]
3323pub enum Timezone {
3324    System, Istanbul, Moscow, Kaliningrad, Samara, Ekaterinburg, Omsk, Krasnoyarsk, Irkutsk, Yakutsk,
3325    Vladivostok, Magadan, Kamchatka, Shanghai, London, Paris, Berlin, Madrid, Rome, Amsterdam, Stockholm, Oslo,
3326    Helsinki, Athens, NewYork, Chicago, Denver, LosAngeles, Anchorage, Honolulu, PuertoRico
3327}
3328
3329impl std::fmt::Display for Timezone {
3330    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3331        match self {
3332            Timezone::System => write!(f, "SYSTEM"), Timezone::Istanbul => write!(f, "Europe/Istanbul"), Timezone::Moscow => write!(f, "Europe/Moscow"),
3333            Timezone::Kaliningrad => write!(f, "Europe/Kaliningrad"), Timezone::Samara => write!(f, "Europe/Samara"), Timezone::Ekaterinburg => write!(f, "Asia/Yekaterinburg"),
3334            Timezone::Omsk => write!(f, "Asia/Omsk"), Timezone::Krasnoyarsk => write!(f, "Asia/Krasnoyarsk"), Timezone::Irkutsk => write!(f, "Asia/Irkutsk"),
3335            Timezone::Yakutsk => write!(f, "Asia/Yakutsk"), Timezone::Vladivostok => write!(f, "Asia/Vladivostok"), Timezone::Magadan => write!(f, "Asia/Magadan"),
3336            Timezone::Kamchatka => write!(f, "Asia/Kamchatka"), Timezone::Shanghai => write!(f, "Asia/Shanghai"), Timezone::London => write!(f, "Europe/London"),
3337            Timezone::Paris => write!(f, "Europe/Paris"), Timezone::Berlin => write!(f, "Europe/Berlin"), Timezone::Madrid => write!(f, "Europe/Madrid"),
3338            Timezone::Rome => write!(f, "Europe/Rome"), Timezone::Amsterdam => write!(f, "Europe/Amsterdam"), Timezone::Stockholm => write!(f, "Europe/Stockholm"),
3339            Timezone::Oslo => write!(f, "Europe/Oslo"), Timezone::Helsinki => write!(f, "Europe/Helsinki"), Timezone::Athens => write!(f, "Europe/Athens"),
3340            Timezone::NewYork => write!(f, "America/New_York"), Timezone::Chicago => write!(f, "America/Chicago"), Timezone::Denver => write!(f, "America/Denver"),
3341            Timezone::LosAngeles => write!(f, "America/Los_Angeles"), Timezone::Anchorage => write!(f, "America/Anchorage"), Timezone::Honolulu => write!(f, "Pacific/Honolulu"),
3342            Timezone::PuertoRico => write!(f, "America/Puerto_Rico")
3343        }
3344    }
3345}
3346
3347/// Enum that benefits you to define what you want with a foreign key.
3348#[derive(Debug, Clone)]
3349pub enum ForeignKeyActions {
3350    Cascade, Restrict, SetNull, NoAction, SetDefault
3351}
3352
3353impl std::fmt::Display for ForeignKeyActions {
3354    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3355        match self {
3356            &ForeignKeyActions::Cascade => write!(f, "CASCADE"),
3357            &ForeignKeyActions::NoAction => write!(f, "NO ACTION"),
3358            &ForeignKeyActions::Restrict => write!(f, "RESTRICT"),
3359            &ForeignKeyActions::SetNull => write!(f, "SET NULL"),
3360            &ForeignKeyActions::SetDefault => write!(f, "SET DEFAULT")
3361        }
3362    }
3363}
3364
3365#[cfg(test)]
3366mod test {
3367    use super::*;
3368
3369    #[test]
3370    pub fn test_schema_query_declarative(){
3371        let schema = SchemaBuilder::create("blog_website").unwrap().if_not_exists().finish();
3372
3373        assert_eq!("CREATE DATABASE IF NOT EXISTS blog_website;", schema);
3374    }
3375
3376    #[test]
3377    pub fn test_schema_query_imperative(){
3378        let mut schema = SchemaBuilder::create("blog_website").unwrap();
3379        schema.if_not_exists();
3380        let schema_query = schema.finish();
3381
3382        assert_eq!("CREATE DATABASE IF NOT EXISTS blog_website;", schema_query);
3383    }
3384
3385    #[test]
3386    pub fn test_use_another_schema(){
3387        let schema = SchemaBuilder::use_another_schema("chat_website").unwrap().finish();
3388
3389        assert_eq!("USE chat_website;", schema);
3390    }
3391
3392    #[test]
3393    pub fn test_insert_query(){
3394        let columns = vec!["title", "author", "description"];
3395        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())];
3396    
3397        let insert_query = QueryBuilder::insert(columns, values).unwrap().table("blogs").finish();
3398
3399        println!("{}", insert_query);
3400        assert_eq!("INSERT INTO blogs (title, author, description) VALUES ('What's Up?', 'John Doe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');".to_string(), 
3401                    insert_query);
3402    }
3403
3404    #[test]
3405    pub fn test_update_query(){
3406        let update_query = QueryBuilder::update().unwrap().table("blogs").set("title", ValueType::String("Hello Rust!".to_string())).set("author", ValueType::String("Necdet".to_string())).finish();
3407
3408        assert_eq!("UPDATE blogs SET title = 'Hello Rust!', author = 'Necdet';", update_query);
3409    }
3410
3411    #[test]
3412    pub fn test_delete_query(){
3413        let delete_query = QueryBuilder::delete().unwrap().table("blogs").where_("id", "=", ValueType::String("1".to_string())).finish();
3414
3415        assert_eq!("DELETE FROM blogs WHERE id = '1';", delete_query);
3416    }
3417
3418    #[test]
3419    pub fn test_select_query_declarative(){
3420        let mut select = QueryBuilder::select(["id", "title", "description", "point"].to_vec()).unwrap();
3421
3422        let select_query = select.table("blogs")
3423                                    .where_("id", "=", ValueType::Int32(10))
3424                                    .and("point", ">", ValueType::Int8(90))
3425                                    .or("id", "=", ValueType::Int64(20))
3426                                    .finish();
3427
3428        assert_eq!("SELECT id, title, description, point FROM blogs WHERE id = 10 AND point > 90 OR id = 20;", select_query)
3429    }
3430
3431    #[test]
3432    pub fn test_select_query_imperative(){
3433        let mut select = QueryBuilder::select(["*"].to_vec()).unwrap();
3434
3435        let select_query = select.table("blogs");
3436        select_query.where_("id", "=", ValueType::Uint8(5));
3437        select_query.or("id", "=", ValueType::Usize(25));
3438
3439        let finish_the_select_query = select_query.finish();
3440
3441        assert_eq!("SELECT * FROM blogs WHERE id = 5 OR id = 25;", finish_the_select_query);
3442    }
3443
3444    #[test]
3445    pub fn test_create_table() {
3446        let mut table_builder_2 = TableBuilder::create("blabla", "projects");
3447        let table_builder_2 = table_builder_2.if_not_exists();
3448    
3449        table_builder_2.add_column("id").col_type("INT").primary_key().auto_increment();
3450        table_builder_2.add_column("name").col_type("VARCHAR(40)").not_null();
3451        table_builder_2.add_column("owner_id").col_type("INT").not_null();
3452        
3453        // if we create a table, the first ForeignKeyItem's table field is not necessary.
3454        let opts = ForeignKey {
3455            first: ForeignKeyItem { table: "".to_string(), column: "owner_id".to_string() },
3456            second: ForeignKeyItem { table: "users".to_string(), column: "id".to_string() },
3457            constraint: None,
3458            on_delete: Some(ForeignKeyActions::Cascade),
3459            on_update: None
3460        };
3461        
3462        table_builder_2.foreign_key(opts);
3463    
3464        let table_builder_2 = table_builder_2.finish();
3465
3466        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();
3467
3468        assert_eq!(raw_query, table_builder_2);
3469    }
3470
3471    #[test]
3472    pub fn test_time_value_type(){
3473        let columns = ["name", "password", "last_login"].to_vec();
3474        let values = [ValueType::String("necoo33".to_string()), ValueType::String("123456".to_string()), ValueType::Datetime("CURRENT_TIMESTAMP".to_string())].to_vec();
3475    
3476        let time_insert_test = QueryBuilder::insert(columns, values).unwrap().table("users").finish();
3477
3478        assert_eq!(time_insert_test, "INSERT INTO users (name, password, last_login) VALUES ('necoo33', '123456', CURRENT_TIMESTAMP);");
3479
3480        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();
3481
3482        assert_eq!(time_update_test, "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE name = 'necoo33';")
3483    }
3484
3485    #[test]
3486    pub fn test_unix_epoch_times(){
3487        let columns = ["name", "password", "last_login"].to_vec();
3488        let values = [ValueType::String("necoo33".to_string()), ValueType::String("123456".to_string()), ValueType::EpochTime(134523452)].to_vec();
3489    
3490        let time_insert_with_unix_epoch_times_test = QueryBuilder::insert(columns, values).unwrap().table("users").finish();
3491        assert_eq!(time_insert_with_unix_epoch_times_test, "INSERT INTO users (name, password, last_login) VALUES ('necoo33', '123456', FROM_UNIXTIME(134523452));");
3492    
3493        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();
3494
3495        assert_eq!(time_update_with_unix_epoch_times_test, "UPDATE users SET last_login = FROM_UNIXTIME(3456436) WHERE name = 'necoo33';");
3496
3497        let columns = ["name", "password", "last_login", "created_at"].to_vec();
3498
3499        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();
3500
3501        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;")
3502    }
3503
3504    #[test]
3505    pub fn test_where_ins(){
3506        let columns = ["name", "age", "id", "last_login"].to_vec();
3507
3508        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3509
3510        let test_where_in = QueryBuilder::select(columns).unwrap().table("users").where_in("id", &ids).finish();
3511
3512        assert_eq!(test_where_in, "SELECT name, age, id, last_login FROM users WHERE id IN (1, 12, 8);");
3513
3514        let columns = ["name", "age", "id", "last_login"].to_vec();
3515
3516        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int32(8)].to_vec();
3517
3518        let test_where_not_in = QueryBuilder::select(columns).unwrap().table("users").where_not_in("id", &ids).finish();
3519
3520        assert_eq!(test_where_not_in, "SELECT name, age, id, last_login FROM users WHERE id NOT IN (1, 12, 8);");
3521
3522        let columns = ["name", "age", "id", "last_login"].to_vec();
3523
3524        let test_where_in_custom = QueryBuilder::select(columns).unwrap().table("users").where_in_custom("id", "1, 12, 8").finish();
3525
3526        assert_eq!(test_where_in_custom, "SELECT name, age, id, last_login FROM users WHERE id IN (1, 12, 8);");
3527
3528        let columns = ["name", "age", "id", "last_login"].to_vec();
3529
3530        let test_where_not_in_custom = QueryBuilder::select(columns).unwrap().table("users").where_not_in_custom("id", "1, 12, 8").finish();
3531
3532        assert_eq!(test_where_not_in_custom, "SELECT name, age, id, last_login FROM users WHERE id NOT IN (1, 12, 8);");
3533
3534        // test AND IN's
3535
3536        let columns = ["name", "id", "last_login"].to_vec();
3537
3538        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3539
3540        let test_and_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).and_in("id", &ids).finish();
3541
3542        assert_eq!(test_and_in, "SELECT name, id, last_login FROM users WHERE age > 35 AND id IN (1, 12, 8);");
3543
3544        let columns = ["name", "id", "last_login"].to_vec();
3545
3546        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3547
3548        let test_and_not_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).and_not_in("id", &ids).finish();
3549
3550        assert_eq!(test_and_not_in, "SELECT name, id, last_login FROM users WHERE age > 35 AND id NOT IN (1, 12, 8);");
3551
3552        // test OR IN's
3553
3554        let columns = ["name", "id", "last_login"].to_vec();
3555
3556        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3557
3558        let test_or_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).or_in("id", &ids).finish();
3559
3560        assert_eq!(test_or_in, "SELECT name, id, last_login FROM users WHERE age > 35 OR id IN (1, 12, 8);");
3561
3562        let columns = ["name", "id", "last_login"].to_vec();
3563
3564        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3565
3566        let test_or_not_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).or_not_in("id", &ids).finish();
3567
3568        assert_eq!(test_or_not_in, "SELECT name, id, last_login FROM users WHERE age > 35 OR id NOT IN (1, 12, 8);")
3569    }
3570
3571    #[test]
3572    pub fn test_count() {
3573        let count_of_users = QueryBuilder::count("*", None).table("users").where_("age", ">", ValueType::Int32(25)).finish();
3574
3575        assert_eq!(count_of_users, "SELECT COUNT(*) FROM users WHERE age > 25;".to_string());
3576
3577        let count_of_users_as_length = QueryBuilder::count("*", Some("length")).table("users").finish();
3578
3579        assert_eq!(count_of_users_as_length, "SELECT COUNT(*) AS length FROM users;".to_string());
3580    }
3581
3582    #[test]
3583    pub fn test_json_extract(){
3584        // tests with "select()" constructor
3585
3586        let select_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").finish();
3587
3588        assert_eq!(select_query_1, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students;".to_string());
3589        
3590        let select_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").where_("successfull", "=", ValueType::Int8(1)).finish();
3591
3592        assert_eq!(select_query_2, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students WHERE successfull = 1;".to_string());
3593        
3594        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();
3595
3596        assert_eq!(select_query_3, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students WHERE JSON_EXTRACT(points, '$.name') > 85;".to_string());
3597
3598        // tests with ".where_cond()" method
3599
3600        let with_where = QueryBuilder::delete().unwrap().table("users").where_("id", ">", ValueType::Int32(200)).json_extract("id", ".user_id", None).finish();
3601
3602        assert_eq!(with_where, "DELETE FROM users WHERE JSON_EXTRACT(id, '$.user_id') > 200;".to_string());
3603
3604        // tests with ".table()" method
3605        
3606        let fields = ["name", "age"].to_vec();
3607        
3608        let with_table = QueryBuilder::select(fields).unwrap().table("users").json_extract("id", ".user_id", None).finish();
3609
3610        assert_eq!(with_table, "SELECT JSON_EXTRACT(id, '$.user_id') FROM users;".to_string());
3611
3612        // tests with ".and()" method
3613
3614        let fields = ["name", "age"].to_vec();
3615
3616        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();
3617
3618        assert_eq!(with_and_1, "SELECT name, age FROM height WHERE weight > 60 AND JSON_EXTRACT(height, '$.student_height') > 1.7;".to_string());
3619    
3620        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();
3621
3622        assert_eq!(with_and_2, "SELECT * FROM students WHERE weight > 60 AND JSON_EXTRACT(height, '$.student_height') > 1.7;".to_string());
3623
3624        // tests with ".or()" method
3625
3626        let fields = ["name", "age"].to_vec();
3627
3628        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();
3629
3630        assert_eq!(with_or_1, "SELECT name, age FROM height WHERE weight > 60 OR JSON_EXTRACT(height, '$.student_height') > 1.71;".to_string());
3631    
3632        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();
3633
3634        assert_eq!(with_or_2, "SELECT * FROM students WHERE weight > 60 OR JSON_EXTRACT(height, '$.student_height') > 1.71;".to_string());
3635
3636        // tests with "count()" constructor
3637
3638        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();
3639
3640        assert_eq!(count_query_1, "SELECT JSON_EXTRACT(age, '$.student_age') AS value, COUNT(*) FROM students GROUP BY points HAVING points > 75;".to_string());
3641
3642        // tests with ".order_by()" method
3643        
3644        let fields = ["title", "desc", "created_at", "updated_at", "keywords", "pics", "likes"].to_vec();
3645
3646        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();
3647
3648        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());
3649    
3650        // tests with ".json_extract()" method
3651
3652        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();
3653
3654        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());
3655    }
3656
3657    #[test]
3658    pub fn test_json_contains(){
3659        // test with "select()" constructor:
3660
3661        let ins = [ValueType::Int32(1), ValueType::Int32(5), ValueType::Int64(11)].to_vec();
3662        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();
3663
3664        assert_eq!(select_query, "SELECT JSON_CONTAINS(pic, '\"/files/hello.jpg\"', '$.path') FROM users WHERE id IN (1, 5, 11);".to_string());
3665
3666        // test with ".where_cond()" method:
3667
3668        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();
3669
3670        assert_eq!(where_query, "SELECT * FROM users WHERE JSON_CONTAINS(pic, '\"blablabla.jpg\"', '$.name');".to_string());
3671
3672        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();
3673
3674        assert_eq!(and_query_1, "SELECT * FROM users WHERE age > 15 AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3675
3676        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();
3677
3678        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());
3679        
3680        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();
3681    
3682        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());
3683
3684        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();
3685    
3686        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());
3687
3688        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();
3689    
3690        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());
3691        
3692        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();
3693
3694        assert_eq!(or_query_1, "SELECT * FROM users WHERE age > 15 OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3695        
3696        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();
3697        
3698        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());
3699                
3700        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();
3701            
3702        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());
3703        
3704        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();
3705            
3706        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());
3707        
3708        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();
3709            
3710        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());
3711
3712        let name = ValueType::JsonString("necdet".to_string());
3713        let id = ValueType::Int32(1);
3714        let is_active = ValueType::Boolean(true);
3715
3716        let object = vec![("name", &name), ("id", &id), ("isActive", &is_active)];
3717
3718        let mysql_json_object = JsonValue::MysqlJsonObject(&object);
3719
3720        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();
3721
3722        assert_eq!("SELECT * FROM users WHERE JSON_CONTAINS(pic, JSON_OBJECT('name', \"necdet\", 'id', 1, 'isActive', true), '$');", where_query_2)
3723    }
3724
3725    #[test]
3726    pub fn test_like_later_than_where_keywords(){
3727        let mut like_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap();
3728
3729        let like_query_1 = like_query_1.table("blogs")
3730                                                      .where_("id", "=", ValueType::Int32(5))
3731                                                      .like(["title", "description"].to_vec(), "hello")
3732                                                      .finish();
3733
3734        assert_eq!(like_query_1, "SELECT * FROM blogs WHERE id = 5 AND (title LIKE '%hello%' OR description LIKE '%hello%');");
3735    
3736        let mut like_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap();
3737
3738        let ins = vec![ValueType::Int32(1), ValueType::Int32(2), ValueType::Int32(3)];
3739        let like_query_2 = like_query_2.table("blogs")
3740                                                          .where_in("id", &ins)
3741                                                          .like(["title", "description", "keywords"].to_vec(), "necdet")
3742                                                          .limit(10)
3743                                                          .offset(0)
3744                                                          .finish();
3745
3746        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;")
3747    }
3748
3749    #[test]
3750    pub fn test_ordering_functions(){
3751        let order_by_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by("id", "asc").order_by("weight", "desc").order_by("point", "asc").finish();
3752
3753        assert_eq!(order_by_query, "SELECT * FROM users ORDER BY id ASC, weight DESC, point ASC;");
3754
3755        let order_by_random_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_random().finish();
3756
3757        assert_eq!(order_by_random_query, "SELECT * FROM users ORDER BY RAND();");
3758
3759        let roles = ["admin", "moderator", "member", "guest"].to_vec();
3760        let field_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles.clone()).finish();
3761
3762        assert_eq!(field_query_1, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest');");
3763
3764        let field_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by("id", "asc").order_by_field("role", roles.clone()).finish();
3765
3766        assert_eq!(field_query_2, "SELECT * FROM users ORDER BY id ASC, FIELD(role, 'admin', 'moderator', 'member', 'guest');");
3767
3768        let field_query_3 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles.clone()).order_by("id", "asc").finish();
3769
3770        assert_eq!(field_query_3, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest'), id ASC;");
3771        
3772        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();
3773
3774        assert_eq!(field_query_4, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest'), FIELD(status, 'active', 'banned', 'unverified');");
3775    }
3776
3777    #[test]
3778    pub fn test_unions(){
3779        let mut union_1 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap();
3780        union_1.table("users").where_("age", ">", ValueType::Int32(7));
3781
3782        let union_2 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap()
3783                                                          .table("users")
3784                                                          .where_("age", "<", ValueType::Int32(15))
3785                                                          .union(vec![union_1])
3786                                                          .finish();
3787
3788        assert_eq!(union_2, "(SELECT name, age, id FROM users WHERE age < 15) UNION (SELECT name, age, id FROM users WHERE age > 7);");
3789
3790        let mut union_1 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
3791        union_1.table("blogs").like(vec!["title"], "text");
3792
3793        let mut union_2 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
3794        union_2.table("blogs").like(vec!["description"], "some text");
3795
3796        let union_3 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap()
3797                                                              .table("blogs")
3798                                                              .where_("published", "=", ValueType::Boolean(true))
3799                                                              .union_all(vec![union_1, union_2])
3800                                                              .finish();
3801
3802        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%');");
3803    }
3804
3805    #[test]
3806    pub fn test_json_value(){
3807        let name = ValueType::JsonString("necdet".to_string());
3808        let age = ValueType::Int8(25);
3809        let id = ValueType::Int32(1);
3810
3811        let values = vec![("name", &name), ("age", &age), ("id", &id)];
3812
3813        let json_object = JsonValue::Object(&values);
3814
3815        assert_eq!("{\"name\": \"necdet\", \"age\": 25, \"id\": 1}", json_object.to_string());
3816
3817        let mysql_json_object = JsonValue::MysqlJsonObject(&values);
3818
3819        assert_eq!("JSON_OBJECT('name', \"necdet\", 'age', 25, 'id', 1)", mysql_json_object.to_string());
3820
3821        let name2 = ValueType::JsonString("cevdet".to_string());
3822        let age2 = ValueType::Int8(24);
3823        let id2 = ValueType::Int32(2);
3824
3825        let name3 = ValueType::JsonString("serap".to_string());
3826        let age3 = ValueType::Int8(21);
3827        let id3 = ValueType::Int32(3);
3828
3829        let object1 = vec![("name", &name), ("age", &age), ("id", &id)];
3830        let object2 = vec![("name", &name2), ("age", &age2), ("id", &id2)];
3831        let object3 = vec![("name", &name3), ("age", &age3), ("id", &id3)];
3832
3833        let objects = vec![object1, object2, object3];
3834        
3835        let json_array = JsonValue::ObjectArray(&objects);
3836
3837        assert_eq!("[{\"name\": \"necdet\", \"age\": 25, \"id\": 1}, {\"name\": \"cevdet\", \"age\": 24, \"id\": 2}, {\"name\": \"serap\", \"age\": 21, \"id\": 3}]", json_array.to_string());
3838    }
3839
3840    #[test]
3841    pub fn test_json_array_append(){
3842        let lesson = ("lesson", &ValueType::String("math".to_string()));
3843        let point = ("point", &ValueType::Int32(100));
3844
3845        let values = vec![lesson, point];
3846        
3847        let object = JsonValue::MysqlJsonObject(&values);
3848
3849        let query = QueryBuilder::update().unwrap()
3850                                         .table("users")
3851                                         .json_array_append("points", Some(""), object.clone())
3852                                         .where_("id", "=", ValueType::Int8(1))
3853                                         .finish();
3854
3855        assert_eq!("UPDATE users SET points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3856
3857        let query = QueryBuilder::update().unwrap()
3858                                         .table("users")
3859                                         .set("status", ValueType::String("passed".to_string()))
3860                                         .json_array_append("points", Some(""), object)
3861                                         .where_("id", "=", ValueType::Int8(1))
3862                                         .finish();
3863
3864        assert_eq!("UPDATE users SET status = 'passed', points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3865    }
3866
3867    #[test]
3868    pub fn test_json_remove() {
3869        let query = QueryBuilder::update().unwrap()
3870                                         .table("blogs")
3871                                         .json_remove("likes", vec!["[10]"])
3872                                         .where_("blog_id", "=", ValueType::Int32(20))
3873                                         .finish();
3874
3875        assert_eq!(query, "UPDATE blogs SET likes = JSON_REMOVE(likes, '$[10]') WHERE blog_id = 20;");
3876        
3877        let query = QueryBuilder::update().unwrap()
3878                                         .table("blogs")
3879                                         .set("blabla", ValueType::Int32(50))
3880                                         .json_remove("likes", vec!["[10]", "[11]", "[12]"])
3881                                         .where_("blog_id", "=", ValueType::Int32(20))
3882                                         .finish();
3883
3884        println!("{}", query)
3885    }
3886
3887    #[test]
3888    pub fn test_json_set_and_json_replace(){
3889        let lesson = ("lesson", &ValueType::String("math".to_string()));
3890        let point = ("point", &ValueType::Int32(100));
3891
3892        let values = vec![lesson, point];
3893        
3894        let object = JsonValue::MysqlJsonObject(&values);
3895
3896        let query = QueryBuilder::update().unwrap()
3897                                                        .table("users")
3898                                                        .json_set("points", "[0]", object)
3899                                                        .where_("id", "=", ValueType::Int32(1))
3900                                                        .finish();
3901
3902        assert_eq!("UPDATE users SET points = JSON_SET(points, '$[0]', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3903
3904        let value = ValueType::Int32(100);
3905        let value = JsonValue::Initial(&value);
3906
3907        let query = QueryBuilder::update().unwrap()
3908                                         .table("users")
3909                                         .json_replace("points", "[0].point", value)
3910                                         .where_("id", "=", ValueType::Int32(1))
3911                                         .finish();
3912
3913        assert_eq!("UPDATE users SET points = JSON_REPLACE(points, '$[0].point', 100) WHERE id = 1;", query)
3914    }
3915
3916    #[test]
3917    pub fn test_json_value_initial_bugfix(){
3918        let file_name_val = ValueType::JsonString("chemistry".to_string());
3919        let file_name_val = JsonValue::Initial(&file_name_val);
3920
3921        let query = QueryBuilder::select(vec!["lesson_points"]).unwrap()
3922                                         .json_extract("points", &format!("[{}]", 2), Some("point"))
3923                                         .table("students")
3924                                         .where_("id", "=", ValueType::Int32(5))
3925                                         .and("adsf", "=", ValueType::Null)
3926                                         .json_contains("points", file_name_val, Some(&format!("[{}].name", 0)))
3927                                         .finish();
3928
3929        assert_eq!("SELECT JSON_EXTRACT(points, '$[2]') AS point FROM students WHERE id = 5 AND JSON_CONTAINS(points, '\"chemistry\"', '$[0].name');", query);
3930    }
3931
3932    #[test]
3933    pub fn test_timezones(){
3934        let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").time_zone(Timezone::Istanbul).finish();
3935
3936        assert_eq!(query, "SET time_zone = Europe/Istanbul; SELECT * FROM users;");
3937        
3938        let query = QueryBuilder::select(vec!["*"]).unwrap()
3939                                         .table("users")
3940                                         .global_time_zone(Timezone::Amsterdam)
3941                                         .where_("id", "=", ValueType::Int32(3))
3942                                         .and("surname", "=", ValueType::String("Doe".to_string()))
3943                                         .finish();
3944
3945        assert_eq!(query, "SET GLOBAL time_zone = Europe/Amsterdam; SELECT * FROM users WHERE id = 3 AND surname = 'Doe';");
3946
3947        let query = QueryBuilder::update().unwrap().table("users").time_zone(Timezone::NewYork).set("age", ValueType::Int32(26)).set("last_online_date", ValueType::Datetime("CURRENT_TIMESTAMP".to_string())).where_("id", "=", ValueType::Int32(234)).finish();
3948
3949        assert_eq!(query, "SET time_zone = America/New_York; UPDATE users SET age = 26, last_online_date = CURRENT_TIMESTAMP WHERE id = 234;");
3950
3951        let query = QueryBuilder::update().unwrap().table("users").set("age", ValueType::Int32(26)).global_time_zone(Timezone::NewYork).set("last_online_date", ValueType::Datetime("CURRENT_TIMESTAMP".to_string())).where_("id", "=", ValueType::Int32(234)).finish();
3952
3953        assert_eq!(query, "SET GLOBAL time_zone = America/New_York; UPDATE users SET age = 26, last_online_date = CURRENT_TIMESTAMP WHERE id = 234;")
3954    }
3955}