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