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    /// it adds the `INNER JOIN` keyword with it's synthax.
1136    /// ```rust
1137    /// 
1138    /// use qubl::{QueryBuilder, ValueType};
1139    /// 
1140    /// fn main(){ 
1141    ///    let query = QueryBuilder::select(vec!["*"]).unwrap()
1142    ///                             .table("students s")
1143    ///                             .inner_join("grades g", "s.id", "=", "g.student_id")
1144    ///                             .where_("id", "=", ValueType::Int32(10))
1145    ///                             .finish();
1146    ///
1147    ///    assert_eq!(query, "SELECT * FROM students s INNER JOIN grades g ON s.id = g.student_id WHERE id = 10;");
1148    /// }
1149    /// 
1150    /// ```
1151    pub fn inner_join(&mut self, table: &str, left: &str, mark: &str, right: &str) -> &mut Self {
1152        self.query = format!("{} INNER JOIN {} ON {} {} {}", self.query, table, left, mark, right);
1153        self.list.push(KeywordList::InnerJoin);
1154        self
1155    }
1156
1157     /// it adds the `LEFT JOIN` keyword with it's synthax.
1158    /// ```rust
1159    /// 
1160    /// use qubl::{QueryBuilder, ValueType};
1161    /// 
1162    /// fn main(){ 
1163    ///    let query = QueryBuilder::select(vec!["*"]).unwrap()
1164    ///                             .table("students s")
1165    ///                             .left_join("grades g", "s.id", "=", "g.student_id")
1166    ///                             .where_("id", "=", ValueType::Int32(10))
1167    ///                             .finish();
1168    ///
1169    ///    assert_eq!(query, "SELECT * FROM students s LEFT JOIN grades g ON s.id = g.student_id WHERE id = 10;");
1170    /// }
1171    /// 
1172    /// ```
1173    pub fn left_join(&mut self, table: &str, left: &str, mark: &str, right: &str) -> &mut Self {
1174        self.query = format!("{} LEFT JOIN {} ON {} {} {}", self.query, table, left, mark, right);
1175        self.list.push(KeywordList::LeftJoin);
1176        self
1177    }
1178
1179
1180    /// it adds the `UNION` keyword and its synthax. You can pass multiple queries to union with:
1181    /// 
1182    /// ```rust
1183    /// 
1184    /// use qubl::{QueryBuilder, ValueType};
1185    /// 
1186    /// fn main(){
1187    ///     let mut union_1 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap();
1188    ///     union_1.table("users").where_("age", ">", ValueType::Int32(7));
1189    ///
1190    ///     let union_2 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap()
1191    ///                                .table("users")
1192    ///                                .where_("age", "<", ValueType::Int32(15))
1193    ///                                .union(vec![union_1])
1194    ///                                .finish();
1195    ///
1196    ///     assert_eq!(union_2, "(SELECT name, age, id FROM users WHERE age < 15) UNION (SELECT name, age, id FROM users WHERE age > 7);");
1197    /// }
1198    /// 
1199    /// ```
1200    pub fn union(&mut self, others: Vec<QueryBuilder<'_>>) -> &mut Self {
1201        match self.list.last() {
1202            Some(keyword) => {
1203                match keyword {
1204                    KeywordList::Union | KeywordList::UnionAll => {
1205                        for other in others {
1206                            self.query = format!("{} UNION ({})", self.query, other.query)
1207                        }
1208                    },
1209                    _ => {
1210                        self.query = format!("({})", self.query);
1211                        
1212                        for other in others {
1213                            self.query = format!("{} UNION ({})", self.query, other.query)
1214                        }
1215                    }
1216                }
1217            },
1218            None => panic!("it's impossible to came here!")
1219        }
1220
1221        self.list.push(KeywordList::Union);
1222
1223        self
1224    }
1225
1226
1227    /// it adds the `UNION` keyword and its synthax. You can pass multiple queries to union with:
1228    /// 
1229    /// ```rust
1230    /// 
1231    /// use qubl::{QueryBuilder, ValueType};
1232    /// 
1233    /// fn main(){
1234    ///     let mut union_1 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
1235    ///     union_1.table("blogs").like(vec!["title"], "text");
1236    ///
1237    ///     let mut union_2 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
1238    ///     union_2.table("blogs").like(vec!["description"], "some text");
1239    ///
1240    ///     let union_3 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap()
1241    ///                                .table("blogs")
1242    ///                                .where_("published", "=", ValueType::Boolean(true))
1243    ///                                .union_all(vec![union_1, union_2])
1244    ///                                .finish();
1245    ///
1246    ///     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%');");
1247    /// }
1248    /// 
1249    /// ```
1250    /// 
1251    pub fn union_all(&mut self, others: Vec<QueryBuilder<'_>>) -> &mut Self {
1252        match self.list.last() {
1253            Some(keyword) => {
1254                match keyword {
1255                    KeywordList::Union | KeywordList::UnionAll => {
1256                        for other in others {
1257                            self.query = format!("{} UNION ALL ({})", self.query, other.query)
1258                        }
1259                    },
1260                    _ => {
1261                        self.query = format!("({})", self.query);
1262                        
1263                        for other in others {
1264                            self.query = format!("{} UNION ALL ({})", self.query, other.query)
1265                        }
1266                    }
1267                }
1268            },
1269            None => panic!("it's impossible to came here!")
1270        }
1271
1272        self.list.push(KeywordList::UnionAll);
1273
1274        self
1275    }
1276
1277    /// 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.  
1278    /// 
1279    /// ```rust
1280    /// 
1281    /// use qubl::{QueryBuilder, ValueType};
1282    /// 
1283    /// fn main(){
1284    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
1285    ///                              .table("users")
1286    ///                              .append_custom("WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0")
1287    ///                              .finish();
1288    /// 
1289    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0;")
1290    /// }
1291    /// ```
1292    /// 
1293    pub fn append_custom(&mut self, query: &str) -> &mut Self {
1294        self.query = format!("{} {}", self.query, query);
1295
1296        self
1297    }
1298
1299    /// 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. 
1300    /// 
1301    /// ```rust
1302    /// 
1303    /// use qubl::{QueryBuilder, ValueType, KeywordList};
1304    /// 
1305    /// fn main(){
1306    ///     let query = QueryBuilder::select(vec!["*"]).unwrap()
1307    ///                              .table("users")
1308    ///                              .append_custom("WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0")
1309    ///                              .append_keyword(KeywordList::Where)
1310    ///                              .append_keyword(KeywordList::Field)
1311    ///                              .append_keyword(KeywordList::Limit)
1312    ///                              .append_keyword(KeywordList::Offset)
1313    ///                              .finish();
1314    /// 
1315    ///     assert_eq!(query, "SELECT * FROM users WHERE age > 25 ORDER BY FIELD(role, 'admin', 'member', 'observer') LIMIT 5 OFFSET 0;")
1316    /// }
1317    /// ```
1318    /// 
1319    pub fn append_keyword(&mut self, keyword: KeywordList) -> &mut Self {
1320        self.list.push(keyword);
1321
1322        self
1323    }
1324    
1325    /// 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.
1326    /// 
1327    /// ```rust
1328    /// 
1329    /// use qubl::{QueryBuilder, ValueType};
1330    /// 
1331    /// fn main(){
1332    ///     let query = QueryBuilder::select(["*"].to_vec()).unwrap()
1333    ///                              .json_extract("articles", "[0]", Some("blog1"))
1334    ///                              .json_extract("articles", "[1]", Some("blog2"))
1335    ///                              .json_extract("articles", "[2]", Some("blog3"))
1336    ///                              .table("users")
1337    ///                              .where_("published", "=", ValueType::Int32(1))
1338    ///                              .finish();
1339    /// 
1340    ///     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;")
1341    /// }
1342    /// 
1343    /// ```
1344    pub fn json_extract(&mut self, haystack: &str, needle: &str, _as: Option<&str>) -> &mut Self {
1345        match self.list.last() {
1346            Some(keyword) => {
1347                match keyword {
1348                    KeywordList::Where => {
1349                        if _as.is_some() {
1350                            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.");
1351                        }
1352
1353                        match self.table.as_str() == haystack {
1354                            true => {
1355                                let mut split_the_query = self.query.split(haystack);
1356                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1357
1358                                self.query = format!("SELECT{}{}{}", self.table, string_for_replace, split_the_query.nth(2).unwrap()) 
1359                            },
1360                            false => {
1361                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1362
1363                                self.query = self.query.replace(haystack,&string_for_replace)
1364                            }
1365                        }
1366                    },
1367                    KeywordList::And => {
1368                        if _as.is_some() {
1369                            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.");
1370                        }
1371
1372                        let query_to_comp = format!("AND {}", haystack);
1373
1374                        match self.table.as_str() == haystack {
1375                            true => {
1376                                let mut split_the_query = self.query.split(&query_to_comp);
1377                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1378
1379                                self.query = format!("{}AND {}{}", split_the_query.nth(0).unwrap(), string_for_replace, split_the_query.nth(0).unwrap()) 
1380                            },
1381                            false => {
1382                                match self.query.matches(&query_to_comp).count() {
1383                                    0 => (),
1384                                    1 => {
1385                                        let string_for_replace = format!("AND JSON_EXTRACT({}, '${}')", haystack, needle);
1386
1387                                        self.query = self.query.replace(&query_to_comp,&string_for_replace)
1388                                    }
1389                                    _ => {
1390                                        let split_the_query = self.query.split(&query_to_comp).collect::<Vec<&str>>();
1391
1392                                        let mut last_chunk = "".to_string();
1393                                        let mut new_chunk = "".to_string();
1394                                        let length_of_split = split_the_query.len();
1395                                        
1396                                        for (index, chunk) in split_the_query.into_iter().enumerate() {
1397                                            if index + 1 == length_of_split {
1398                                                last_chunk = chunk.to_string()
1399                                            } else if index == 0 {
1400                                                new_chunk = format!("{}", chunk);
1401                                            } else {
1402                                                new_chunk = format!("{}{}{}", new_chunk, query_to_comp, chunk)
1403                                            }
1404                                        }
1405
1406                                        let string_for_replace = format!("AND JSON_EXTRACT({}, '${}')", haystack, needle);
1407
1408                                        self.query = format!("{} {} {}", new_chunk, string_for_replace, last_chunk)
1409                                    }
1410                                }
1411                            }
1412                        }
1413                    },
1414                    KeywordList::Or => {
1415                        if _as.is_some() {
1416                            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.");
1417                        }
1418
1419                        let query_to_comp = format!("OR {}", haystack);
1420
1421                        match self.table.as_str() == haystack {
1422                            true => {
1423                                let mut split_the_query = self.query.split(&query_to_comp);
1424                                let string_for_replace = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1425
1426                                self.query = format!("{}OR {}{}", split_the_query.nth(0).unwrap(), string_for_replace, split_the_query.nth(0).unwrap()) 
1427                            },
1428                            false => {
1429                                match self.query.matches(&query_to_comp).count() {
1430                                    0 => (),
1431                                    1 => {
1432                                        let string_for_replace = format!("OR JSON_EXTRACT({}, '${}')", haystack, needle);
1433
1434                                        self.query = self.query.replace(&query_to_comp,&string_for_replace)
1435                                    }
1436                                    _ => {
1437                                        let split_the_query = self.query.split(&query_to_comp).collect::<Vec<&str>>();
1438
1439                                        let mut last_chunk = "".to_string();
1440                                        let mut new_chunk = "".to_string();
1441                                        let length_of_split = split_the_query.len();
1442                                        
1443                                        for (index, chunk) in split_the_query.into_iter().enumerate() {
1444                                            if index + 1 == length_of_split {
1445                                                last_chunk = chunk.to_string()
1446                                            } else if index == 0 {
1447                                                new_chunk = format!("{}", chunk);
1448                                            } else {
1449                                                new_chunk = format!("{}{}{}", new_chunk, query_to_comp, chunk)
1450                                            }
1451                                        }
1452
1453                                        let string_for_replace = format!("OR JSON_EXTRACT({}, '${}')", haystack, needle);
1454
1455                                        self.query = format!("{} {} {}", new_chunk, string_for_replace, last_chunk)
1456                                    }
1457                                }
1458                            }
1459                        }
1460                    },
1461                    KeywordList::Select => {
1462                        let string_for_put = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1463
1464                        match _as {
1465                            Some(_as) => self.query = format!("SELECT {} AS {} FROM", string_for_put, _as),
1466                            None => self.query = format!("SELECT {} FROM", string_for_put),
1467                        }
1468                    },
1469                    KeywordList::Table => {
1470                        let string_for_put = format!("JSON_EXTRACT({}, '${}')", haystack, needle);
1471
1472                        match _as {
1473                            Some(_as) => self.query = format!("SELECT {} AS {} FROM {}", string_for_put, _as, self.table),
1474                            None => self.query = format!("SELECT {} FROM {}", string_for_put, self.table),
1475                        }
1476                    },
1477                    KeywordList::OrderBy => {
1478                        if _as.is_some() {
1479                            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.");
1480                        }
1481
1482                        match self.query.matches(" ORDER BY ").count() {
1483                            0 => (),
1484                            1 => {
1485                                let split_the_query = self.query.clone();
1486                                let mut split_the_query = split_the_query.split(" ORDER BY ");
1487
1488                                let string_for_put = format!("ORDER BY JSON_EXTRACT({}, '${}')", haystack, needle);
1489        
1490                                match _as {
1491                                    Some(_as) => self.query = format!("{} {} AS {}", split_the_query.nth(0).unwrap(), string_for_put, _as),
1492                                    None => self.query = format!("{} {}", split_the_query.nth(0).unwrap(), string_for_put)
1493                                }
1494
1495                                match split_the_query.nth(0) {
1496                                    Some(comparison) => {
1497                                        match comparison.ends_with("ASC") || comparison.ends_with("asc") {
1498                                            true => self.query = format!("{} ASC", self.query),
1499                                            false => match comparison.ends_with("DESC") || comparison.ends_with("desc") {
1500                                                true => self.query = format!("{} DESC", self.query),
1501                                                false => ()
1502                                            }
1503                                        }
1504                                    },
1505                                    None => ()
1506                                }
1507                            },
1508                            _ => ()
1509                        }
1510                    },
1511                    KeywordList::Count => {
1512                        let mut split_the_query = self.query.split(" COUNT");
1513
1514                        let string_for_put = match _as {
1515                            Some(_as) => format!("JSON_EXTRACT({}, '${}') AS {}", haystack, needle, _as),
1516                            None => format!("JSON_EXTRACT({}, '${}')", haystack, needle)
1517                        };
1518
1519                        self.query = format!("SELECT {}, COUNT{}", string_for_put, split_the_query.nth(1).unwrap())
1520                    },
1521                    KeywordList::JsonExtract => {
1522                        let mut split_the_query = self.query.split(" FROM");
1523
1524                        match _as {
1525                            Some(_as) => self.query = format!("{}, JSON_EXTRACT({}, '${}') AS {} FROM", split_the_query.nth(0).unwrap(), haystack, needle, _as),
1526                            None => panic!("If you want to chain .json_extract() methods, you have to give them a tag.")
1527                        }
1528                    }
1529                    _ => ()
1530                }
1531            },
1532            None => ()
1533        }
1534        
1535        self.list.push(KeywordList::JsonExtract);
1536        self
1537    }
1538
1539    /// 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.
1540    /// 
1541    /// ```rust
1542    /// 
1543    /// use qubl::{QueryBuilder, ValueType, JsonValue};
1544    /// 
1545    /// fn main(){
1546    ///     let value = ValueType::String("blablabla.jpg".to_string());
1547    ///     let prop = vec![("name", &value)];
1548    /// 
1549    ///     let object = JsonValue::MysqlJsonObject(&prop);
1550    /// 
1551    ///     let query = QueryBuilder::select(["*"].to_vec()).unwrap()
1552    ///                              .table("users")
1553    ///                              .where_("pic", "=", ValueType::String("".to_string()))
1554    ///                              .json_contains("pic", object, Some(".name"))
1555    ///                              .finish();
1556    /// 
1557    ///     assert_eq!(query, "SELECT * FROM users WHERE JSON_CONTAINS(pic, JSON_OBJECT('name', 'blablabla.jpg'), '$.name');")
1558    /// }
1559    /// 
1560    /// ```
1561    pub fn json_contains(&mut self, column: &str, needle: JsonValue, path: Option<&str>) -> &mut Self {
1562        match self.list.last().unwrap() {
1563            KeywordList::Select => match path {
1564                Some(path) => match needle {
1565                    JsonValue::Initial(initial) => match initial {
1566                        ValueType::JsonString(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '\"{}\"', '${}') FROM", column, needle, path),
1567                        ValueType::String(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1568                        ValueType::Datetime(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1569                        _ => self.query = format!("SELECT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1570                    },
1571                    _ => self.query = format!("SELECT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1572                }
1573                None => match needle {
1574                    JsonValue::Initial(initial) => match initial {
1575                        ValueType::JsonString(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '\"{}\"') FROM", column, needle),
1576                        ValueType::String(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}') FROM", column, needle),
1577                        ValueType::Datetime(needle) => self.query = format!("SELECT JSON_CONTAINS({}, '{}') FROM", column, needle),
1578                        _ => self.query = format!("SELECT JSON_CONTAINS({}, {}) FROM", column, needle)
1579                    },
1580                    _ => self.query = format!("SELECT JSON_CONTAINS({}, {}) FROM", column, needle)
1581                }
1582            },
1583            KeywordList::Where => match path {
1584                Some(path) => {
1585                    let mut split_the_query = self.query.split(" WHERE ");
1586
1587                    let first_half = split_the_query.nth(0);
1588
1589                    match needle {
1590                        JsonValue::Initial(initial) => match initial {
1591                            ValueType::JsonString(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '\"{}\"', '${}')", first_half.unwrap(), column, needle, path),
1592                            ValueType::String(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1593                            ValueType::Datetime(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1594                            _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1595                        },
1596                        _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1597                    }
1598                },
1599                None => {
1600                    let mut split_the_query = self.query.split(" WHERE ");
1601
1602                    let first_half = split_the_query.nth(0);
1603
1604                    match needle {
1605                        JsonValue::Initial(initial) => match initial {
1606                            ValueType::JsonString(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '\"{}\"')", first_half.unwrap(), column, needle),
1607                            ValueType::String(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1608                            ValueType::Datetime(needle) => self.query = format!("{} WHERE JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1609                            _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1610                        },
1611                        _ => self.query = format!("{} WHERE JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1612                    }
1613                }
1614            },
1615            KeywordList::And => match path {
1616                Some(path) => {
1617                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1618
1619                    let length_of_the_split_the_query = split_the_query.len();
1620
1621                    match split_the_query.len() {
1622                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1623                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1624                        2 => match needle {
1625                            JsonValue::Initial(initial) => match initial {
1626                                ValueType::JsonString(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1627                                ValueType::String(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1628                                ValueType::Datetime(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1629                                _ => self.query = format!("{} AND JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1630                            },
1631                            _ => self.query = format!("{} AND JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1632                        },
1633                        _ => {
1634                            let mut concatenated_string = String::new();
1635
1636                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1637                                if index == 0 {
1638                                    concatenated_string = chunk.to_string();
1639                                } else if index + 1 != length_of_the_split_the_query {
1640                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1641                                }
1642                            }
1643
1644                            match needle {
1645                                JsonValue::Initial(initial) => match initial {
1646                                    ValueType::JsonString(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1647                                    ValueType::String(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1648                                    ValueType::Datetime(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1649                                    _ => self.query = format!("{}AND JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1650                                },
1651                                _ => self.query = format!("{}AND JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1652                            }
1653                        }
1654                    }
1655                },
1656                None => {
1657                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1658
1659                    let length_of_the_split_the_query = split_the_query.len();
1660
1661                    match split_the_query.len() {
1662                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1663                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1664                        2 => match needle {
1665                            JsonValue::Initial(initial) => match initial {
1666                                ValueType::JsonString(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1667                                ValueType::String(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1668                                ValueType::Datetime(needle) => self.query = format!("{} AND JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1669                                _ => self.query = format!("{} AND JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1670                            },
1671                            _ => self.query = format!("{} AND JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1672                        },
1673                        _ => {
1674                            let mut concatenated_string = String::new();
1675
1676                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1677                                if index == 0 {
1678                                    concatenated_string = chunk.to_string();
1679                                } else if index + 1 != length_of_the_split_the_query {
1680                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1681                                }
1682                            }
1683
1684                            match needle {
1685                                JsonValue::Initial(initial) => match initial {
1686                                    ValueType::JsonString(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1687                                    ValueType::String(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1688                                    ValueType::Datetime(needle) => self.query = format!("{}AND JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1689                                    _ => self.query = format!("{}AND JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1690                                },
1691                                _ => self.query = format!("{}AND JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1692                            }
1693                        }
1694                    }
1695                }
1696            },
1697            KeywordList::Or => match path {
1698                Some(path) => {
1699                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1700
1701                    let length_of_the_split_the_query = split_the_query.len();
1702
1703                    match split_the_query.len() {
1704                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1705                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1706                        2 => match needle {
1707                            JsonValue::Initial(initial) => match initial {
1708                                ValueType::JsonString(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1709                                ValueType::String(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1710                                ValueType::Datetime(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1711                                _ => self.query = format!("{} OR JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1712                            },
1713                            _ => self.query = format!("{} OR JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1714                        },
1715                        _ => {
1716                            let mut concatenated_string = String::new();
1717
1718                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1719                                if index == 0 {
1720                                    concatenated_string = chunk.to_string();
1721                                } else if index + 1 != length_of_the_split_the_query {
1722                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1723                                }
1724                            }
1725
1726                            match needle {
1727                                JsonValue::Initial(initial) => match initial {
1728                                    ValueType::JsonString(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1729                                    ValueType::String(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1730                                    ValueType::Datetime(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1731                                    _ => self.query = format!("{}OR JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1732                                },
1733                                _ => self.query = format!("{}OR JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1734                            }
1735                        }
1736                    }
1737                },
1738                None => {
1739                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1740
1741                    let length_of_the_split_the_query = split_the_query.len();
1742
1743                    match split_the_query.len() {
1744                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1745                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1746                        2 => match needle {
1747                            JsonValue::Initial(initial) => match initial {
1748                                ValueType::JsonString(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1749                                ValueType::String(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1750                                ValueType::Datetime(needle) => self.query = format!("{} OR JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1751                                _ => self.query = format!("{} OR JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1752                            },
1753                            _ => self.query = format!("{} OR JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1754                        },
1755                        _ => {
1756                            let mut concatenated_string = String::new();
1757
1758                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1759                                if index == 0 {
1760                                    concatenated_string = chunk.to_string();
1761                                } else if index + 1 != length_of_the_split_the_query {
1762                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1763                                }
1764                            }
1765
1766                            match needle {
1767                                JsonValue::Initial(initial) => match initial {
1768                                    ValueType::JsonString(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1769                                    ValueType::String(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1770                                    ValueType::Datetime(needle) => self.query = format!("{}OR JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1771                                    _ => self.query = format!("{}OR JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1772                                },
1773                                _ => self.query = format!("{}OR JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1774                            }
1775                        }
1776                    }
1777                }
1778            },
1779            _ => panic!("Wrong usage of '.json_contains()' method, it should be used later than either SELECT, WHERE, AND, OR keywords.")
1780        }
1781
1782        self.list.push(KeywordList::JsonContains);
1783
1784        self
1785    }
1786
1787    /// 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.
1788    /// 
1789    /// ```rust
1790    /// 
1791    /// use qubl::{QueryBuilder, ValueType, JsonValue};
1792    /// 
1793    /// fn main(){
1794    ///     let value = ValueType::String("blablabla.jpg".to_string());
1795    ///     let prop = vec![("name", &value)];
1796    /// 
1797    ///     let object = JsonValue::MysqlJsonObject(&prop);
1798    /// 
1799    ///     let query = QueryBuilder::select(["*"].to_vec()).unwrap()
1800    ///                              .table("users")
1801    ///                              .where_("pic", "=", ValueType::String("".to_string()))
1802    ///                              .not_json_contains("pic", object, Some(".name"))
1803    ///                              .finish();
1804    /// 
1805    ///     assert_eq!(query, "SELECT * FROM users WHERE NOT JSON_CONTAINS(pic, JSON_OBJECT('name', 'blablabla.jpg'), '$.name');")
1806    /// }
1807    /// 
1808    /// ```
1809    pub fn not_json_contains(&mut self, column: &str, needle: JsonValue, path: Option<&str>) -> &mut Self {
1810        match self.list.last().unwrap() {
1811            KeywordList::Select => match path {
1812                Some(path) => match needle {
1813                    JsonValue::Initial(initial) => match initial {
1814                        ValueType::JsonString(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '\"{}\"', '${}') FROM", column, needle, path),
1815                        ValueType::String(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1816                        ValueType::Datetime(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}', '${}') FROM", column, needle, path),
1817                        _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1818                    },
1819                    _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}, '${}') FROM", column, needle, path),
1820                }
1821                None => match needle {
1822                    JsonValue::Initial(initial) => match initial {
1823                        ValueType::JsonString(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '\"{}\"') FROM", column, needle),
1824                        ValueType::String(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}') FROM", column, needle),
1825                        ValueType::Datetime(needle) => self.query = format!("SELECT NOT JSON_CONTAINS({}, '{}') FROM", column, needle),
1826                        _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}) FROM", column, needle)
1827                    },
1828                    _ => self.query = format!("SELECT NOT JSON_CONTAINS({}, {}) FROM", column, needle)
1829                }
1830            },
1831            KeywordList::Where => match path {
1832                Some(path) => {
1833                    let mut split_the_query = self.query.split(" WHERE ");
1834
1835                    let first_half = split_the_query.nth(0);
1836
1837                    match needle {
1838                        JsonValue::Initial(initial) => match initial {
1839                            ValueType::JsonString(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '\"{}\"', '${}')", first_half.unwrap(), column, needle, path),
1840                            ValueType::String(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1841                            ValueType::Datetime(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}', '${}')", first_half.unwrap(), column, needle, path),
1842                            _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1843                        },
1844                        _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {}, '${}')", first_half.unwrap(), column, needle, path)
1845                    }
1846                },
1847                None => {
1848                    let mut split_the_query = self.query.split(" WHERE ");
1849
1850                    let first_half = split_the_query.nth(0);
1851
1852                    match needle {
1853                        JsonValue::Initial(initial) => match initial {
1854                            ValueType::JsonString(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '\"{}\"')", first_half.unwrap(), column, needle),
1855                            ValueType::String(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1856                            ValueType::Datetime(needle) => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, '{}')", first_half.unwrap(), column, needle),
1857                            _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1858                        },
1859                        _ => self.query = format!("{} WHERE NOT JSON_CONTAINS({}, {})", first_half.unwrap(), column, needle)
1860                    }
1861                }
1862            },
1863            KeywordList::And => match path {
1864                Some(path) => {
1865                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1866
1867                    let length_of_the_split_the_query = split_the_query.len();
1868
1869                    match split_the_query.len() {
1870                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1871                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1872                        2 => match needle {
1873                            JsonValue::Initial(initial) => match initial {
1874                                ValueType::JsonString(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1875                                ValueType::String(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1876                                ValueType::Datetime(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1877                                _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1878                            },
1879                            _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1880                        },
1881                        _ => {
1882                            let mut concatenated_string = String::new();
1883
1884                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1885                                if index == 0 {
1886                                    concatenated_string = chunk.to_string();
1887                                } else if index + 1 != length_of_the_split_the_query {
1888                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1889                                }
1890                            }
1891
1892                            match needle {
1893                                JsonValue::Initial(initial) => match initial {
1894                                    ValueType::JsonString(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1895                                    ValueType::String(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1896                                    ValueType::Datetime(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1897                                    _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1898                                },
1899                                _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1900                            }
1901                        }
1902                    }
1903                },
1904                None => {
1905                    let split_the_query = self.query.split(" AND ").collect::<Vec<&str>>();
1906
1907                    let length_of_the_split_the_query = split_the_query.len();
1908
1909                    match split_the_query.len() {
1910                        0 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1911                        1 => panic!("There Is No AND query in QueryBuilder but The AND keyword exist in keyword list, panicking."),
1912                        2 => match needle {
1913                            JsonValue::Initial(initial) => match initial {
1914                                ValueType::JsonString(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1915                                ValueType::String(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1916                                ValueType::Datetime(needle) => self.query = format!("{} AND NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1917                                _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1918                            },
1919                            _ => self.query = format!("{} AND NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
1920                        },
1921                        _ => {
1922                            let mut concatenated_string = String::new();
1923
1924                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1925                                if index == 0 {
1926                                    concatenated_string = chunk.to_string();
1927                                } else if index + 1 != length_of_the_split_the_query {
1928                                    concatenated_string = format!("{} AND {} ", concatenated_string, chunk)
1929                                }
1930                            }
1931
1932                            match needle {
1933                                JsonValue::Initial(initial) => match initial {
1934                                    ValueType::JsonString(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
1935                                    ValueType::String(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1936                                    ValueType::Datetime(needle) => self.query = format!("{}AND NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
1937                                    _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1938                                },
1939                                _ => self.query = format!("{}AND NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
1940                            }
1941                        }
1942                    }
1943                }
1944            },
1945            KeywordList::Or => match path {
1946                Some(path) => {
1947                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1948
1949                    let length_of_the_split_the_query = split_the_query.len();
1950
1951                    match split_the_query.len() {
1952                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1953                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1954                        2 => match needle {
1955                            JsonValue::Initial(initial) => match initial {
1956                                ValueType::JsonString(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '\"{}\"', '${}')", split_the_query[0], column, needle, path),
1957                                ValueType::String(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1958                                ValueType::Datetime(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}', '${}')", split_the_query[0], column, needle, path),
1959                                _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1960                            },
1961                            _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {}, '${}')", split_the_query[0], column, needle, path)
1962                        },
1963                        _ => {
1964                            let mut concatenated_string = String::new();
1965
1966                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
1967                                if index == 0 {
1968                                    concatenated_string = chunk.to_string();
1969                                } else if index + 1 != length_of_the_split_the_query {
1970                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
1971                                }
1972                            }
1973
1974                            match needle {
1975                                JsonValue::Initial(initial) => match initial {
1976                                    ValueType::JsonString(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '\"{}\"', '${}')", concatenated_string, column, needle, path),
1977                                    ValueType::String(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1978                                    ValueType::Datetime(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}', '${}')", concatenated_string, column, needle, path),
1979                                    _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1980                                },
1981                                _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {}, '${}')", concatenated_string, column, needle, path)
1982                            }
1983                        }
1984                    }
1985                },
1986                None => {
1987                    let split_the_query = self.query.split(" OR ").collect::<Vec<&str>>();
1988
1989                    let length_of_the_split_the_query = split_the_query.len();
1990
1991                    match split_the_query.len() {
1992                        0 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1993                        1 => panic!("There Is No OR query in QueryBuilder but The OR keyword exist in keyword list, panicking."),
1994                        2 => match needle {
1995                            JsonValue::Initial(initial) => match initial {
1996                                ValueType::JsonString(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '\"{}\"')",  split_the_query[0], column, needle),
1997                                ValueType::String(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1998                                ValueType::Datetime(needle) => self.query = format!("{} OR NOT JSON_CONTAINS({}, '{}')",  split_the_query[0], column, needle),
1999                                _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
2000                            },
2001                            _ => self.query = format!("{} OR NOT JSON_CONTAINS({}, {})",  split_the_query[0], column, needle)
2002                        },
2003                        _ => {
2004                            let mut concatenated_string = String::new();
2005
2006                            for (index, chunk) in  split_the_query.into_iter().enumerate() {
2007                                if index == 0 {
2008                                    concatenated_string = chunk.to_string();
2009                                } else if index + 1 != length_of_the_split_the_query {
2010                                    concatenated_string = format!("{} OR {} ", concatenated_string, chunk)
2011                                }
2012                            }
2013
2014                            match needle {
2015                                JsonValue::Initial(initial) => match initial {
2016                                    ValueType::JsonString(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '\"{}\"')", concatenated_string, column, needle),
2017                                    ValueType::String(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
2018                                    ValueType::Datetime(needle) => self.query = format!("{}OR NOT JSON_CONTAINS({}, '{}')", concatenated_string, column, needle),
2019                                    _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
2020                                },
2021                                _ => self.query = format!("{}OR NOT JSON_CONTAINS({}, {})", concatenated_string, column, needle)
2022                            }
2023                        }
2024                    }
2025                }
2026            },
2027            _ => panic!("Wrong usage of '.not_json_contains()' method, it should be used later than either SELECT, WHERE, AND, OR keywords.")
2028        }
2029
2030        self.list.push(KeywordList::NotJsonContains);
2031
2032        self
2033    }
2034
2035    /// 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.
2036    /// 
2037    /// ```rust
2038    /// 
2039    /// use qubl::{QueryBuilder, ValueType, JsonValue};
2040    /// 
2041    /// fn main () {
2042    ///     let lesson = ("lesson", &ValueType::String("math".to_string()));
2043    ///     let point = ("point", &ValueType::Int32(100));
2044    ///
2045    ///     let values = vec![lesson, point];
2046    ///
2047    ///     let object = JsonValue::MysqlJsonObject(&values);
2048    ///
2049    ///     let query = QueryBuilder::update().unwrap()
2050    ///                                 .table("users")
2051    ///                                 .json_array_append("points", Some(""), object.clone())
2052    ///                                 .where_("id", "=", ValueType::Int8(1))
2053    ///                                 .finish();
2054    ///
2055    ///     assert_eq!("UPDATE users SET points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
2056    /// }
2057    /// 
2058    /// ```
2059    pub fn json_array_append(&mut self, column: &str, path: Option<&str>, object: JsonValue) -> &mut Self {
2060        match self.list.last() {
2061            Some(keyword) => match keyword {
2062                KeywordList::Set => {
2063                    match path {
2064                        Some(path) => match object {
2065                            JsonValue::Initial(initial) => match initial {
2066                                ValueType::JsonString(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '\"{}\"')", self.query, column, column, path, object),
2067                                ValueType::String(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
2068                                ValueType::Datetime(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
2069                                _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
2070                            },
2071                            _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
2072                        }
2073                        None => match object {
2074                            JsonValue::Initial(initial) => match initial {
2075                                ValueType::JsonString(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '\"{}\"')", self.query, column, column, object),
2076                                ValueType::String(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
2077                                ValueType::Datetime(object) => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
2078                                _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2079                            },
2080                            _ => self.query = format!("{}, {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2081                        }
2082                    }
2083                },
2084                _ => {
2085                    match path {
2086                        Some(path) => match object {
2087                            JsonValue::Initial(initial) => match initial {
2088                                ValueType::JsonString(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '\"{}\"')", self.query, column, column, path, object),
2089                                ValueType::String(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
2090                                ValueType::Datetime(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', '{}')", self.query, column, column, path, object),
2091                                _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
2092                            },
2093                            _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '${}', {})", self.query, column, column, path, object),
2094                        }
2095                        None => match object {
2096                            JsonValue::Initial(initial) => match initial {
2097                                ValueType::JsonString(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '\"{}\"')", self.query, column, column, object),
2098                                ValueType::String(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
2099                                ValueType::Datetime(object) => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', '{}')", self.query, column, column, object),
2100                                _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2101                            },
2102                            _ => self.query = format!("{} SET {} = JSON_ARRAY_APPEND({}, '$', {})", self.query, column, column, object)
2103                        }
2104                    }
2105                }
2106            },
2107            None => panic!("it's impossible to came here!")
2108        }
2109
2110        self.list.push(KeywordList::JsonArrayAppend);
2111        self
2112    }
2113
2114    /// it adds "JSON_REMOVE()" function with it's synthax. You cannot pass empty strings to paths.
2115    /// 
2116    /// ```rust
2117    /// 
2118    /// use qubl::{QueryBuilder, ValueType};
2119    /// 
2120    /// fn main () {
2121    ///   let query = QueryBuilder::update().unwrap()
2122    ///                            .table("blogs")
2123    ///                            .json_remove("likes", vec!["[10]"])
2124    ///                            .where_("blog_id", "=", ValueType::Int32(20))
2125    ///                            .finish();
2126    ///
2127    ///   assert_eq!(query, "UPDATE blogs SET likes = JSON_REMOVE(likes, '$[10]') WHERE blog_id = 20;");
2128    /// }
2129    /// 
2130    /// ```
2131    pub fn json_remove(&mut self, column: &str, paths: Vec<&str>) -> &mut Self {
2132        match paths.iter().any(|path| *path == "") {
2133            true => panic!("Error: a value in the paths cannot be empty string, panicking..."),
2134            false => ()
2135        }
2136
2137        match self.list.last() {
2138            Some(keyword) => match keyword {
2139                KeywordList::Set => {
2140                    self.query = format!("{}, {} = JSON_REMOVE({}", self.query, column, column);
2141
2142                    for path in paths {
2143                        if path.starts_with("$") {
2144                            self.query = format!("{}, '${}'", self.query, path.replace("$", ""))
2145                        } else {
2146                            self.query = format!("{}, '${}'", self.query, path)
2147                        }
2148                    }
2149
2150                    self.query = format!("{})", self.query)
2151                },
2152                _ => {
2153                    self.query = format!("{} SET {} = JSON_REMOVE({}", self.query, column, column);
2154
2155                    for path in paths {
2156                        if path.starts_with("$") {
2157                            self.query = format!("{}, '${}'", self.query, path.replace("$", ""))
2158                        } else {
2159                            self.query = format!("{}, '${}'", self.query, path)
2160                        }
2161                    }
2162
2163                    self.query = format!("{})", self.query)
2164                }
2165            },
2166            None => panic!("it's impossible to came here!")
2167        }
2168
2169        self.list.push(KeywordList::JsonRemove);
2170        self
2171    }
2172
2173    /// It adds `JSON_SET()` function with it's synthax. It updates values with the specified path.
2174    /// 
2175    /// ```rust
2176    /// 
2177    /// use qubl::{QueryBuilder, ValueType, JsonValue};
2178    /// 
2179    /// fn main () {
2180    /// 
2181    /// let lesson = ("lesson", &ValueType::String("math".to_string()));
2182    /// let point = ("point", &ValueType::Int32(100));
2183    ///
2184    /// let values = vec![lesson, point];
2185    ///
2186    /// let object = JsonValue::MysqlJsonObject(&values);
2187    ///
2188    /// let query = QueryBuilder::update().unwrap()
2189    ///                          .table("users")
2190    ///                          .json_set("points", "[0]", object)
2191    ///                          .where_("id", "=", ValueType::Int32(1))
2192    ///                          .finish();
2193    ///
2194    /// assert_eq!("UPDATE users SET points = JSON_SET(points, '$[0]', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
2195    /// 
2196    /// }
2197    /// 
2198    /// ```
2199    pub fn json_set(&mut self, column: &str, path: &str, value: JsonValue) -> &mut Self {
2200        match self.list.last() {
2201            Some(keyword) => match keyword {
2202                KeywordList::Set => match value {
2203                    JsonValue::Initial(initial) => match initial {
2204                        ValueType::JsonString(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2205                        ValueType::String(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2206                        ValueType::Datetime(value) => self.query = format!("{}, {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2207                        _ => self.query = format!("{}, {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value),
2208                    },
2209                    _ => self.query = format!("{}, {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value),
2210                }
2211                _ => match value {
2212                    JsonValue::Initial(initial) => match initial {
2213                        ValueType::JsonString(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2214                        ValueType::String(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2215                        ValueType::Datetime(value) => self.query = format!("{} SET {} = JSON_SET({}, '${}', '{}')", self.query, column, column, path, value),
2216                        _ => self.query = format!("{} SET {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value)
2217                    },
2218                    _ => self.query = format!("{} SET {} = JSON_SET({}, '${}', {})", self.query, column, column, path, value)
2219                }
2220            },
2221            None => panic!("it's impossible to came here!")
2222        }
2223
2224        self.list.push(KeywordList::JsonSet);
2225        self
2226    }
2227
2228    /// It adds `JSON_REPLACE()` function with it's synthax. It updates values with the specified path.
2229    /// 
2230    /// ```rust
2231    /// 
2232    /// use qubl::{QueryBuilder, ValueType, JsonValue};
2233    /// 
2234    /// fn main () {
2235    /// 
2236    /// let value = ValueType::Int32(100);
2237    /// let value = JsonValue::Initial(&value);
2238    ///
2239    /// let query = QueryBuilder::update().unwrap()
2240    ///                          .table("users")
2241    ///                          .json_replace("points", "[0].point", value)
2242    ///                          .where_("id", "=", ValueType::Int32(1))
2243    ///                          .finish();
2244    ///
2245    /// assert_eq!("UPDATE users SET points = JSON_REPLACE(points, '$[0].point', 100) WHERE id = 1;", query)
2246    /// 
2247    /// }
2248    /// 
2249    /// ```
2250    pub fn json_replace(&mut self, column: &str, path: &str, value: JsonValue) -> &mut Self {
2251        match self.list.last() {
2252            Some(keyword) => match keyword {
2253                KeywordList::Set => match value {
2254                    JsonValue::Initial(initial) => match initial {
2255                        ValueType::JsonString(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2256                        ValueType::String(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2257                        ValueType::Datetime(value) => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2258                        _ => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value),
2259                    },
2260                    _ => self.query = format!("{}, {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value),
2261                }
2262                _ => match value {
2263                    JsonValue::Initial(initial) => match initial {
2264                        ValueType::JsonString(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '\"{}\"')", self.query, column, column, path, value),
2265                        ValueType::String(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2266                        ValueType::Datetime(value) => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', '{}')", self.query, column, column, path, value),
2267                        _ => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value)
2268                    },
2269                    _ => self.query = format!("{} SET {} = JSON_REPLACE({}, '${}', {})", self.query, column, column, path, value)
2270                }
2271            },
2272            None => panic!("it's impossible to came here!")
2273        }
2274
2275        self.list.push(KeywordList::JsonSet);
2276        self
2277    }
2278
2279    /// finishes the query and returns the result as string.
2280    pub fn finish(&self) -> String {
2281        return format!("{};", self.query);
2282    }
2283
2284    /// gives you an immutable copy of that instance, just for case if you need to share and potentially mutate it across threads.
2285    pub fn copy(&mut self) -> Self {
2286        Self {
2287            query: self.query.clone(),
2288            table: self.table.clone(),
2289            qtype: self.qtype.clone(),
2290            list: self.list.clone(),
2291            hq: self.hq
2292        }
2293    }
2294
2295    fn load_hqs() -> [&'a str; 26] {
2296        [";", "; drop", "admin' #", "admin'/*", "; union", "or 1 = 1",
2297        "or 1 = 1#", "or 1 = 1/*", "or true = true", "or false = false", "or '1' = '1'", "or '1' = '1'#",
2298        "or '1' = '1'/*", "; sleep(", "--", "drop table", "drop schema", "select if", "union select",
2299        "union all", "exec", "master..", "masters..", "information_schema", "load_file", "alter user"]
2300    }
2301
2302    fn sanitize_column(&mut self, column: &str)  -> std::result::Result<(), std::io::Error>  {
2303        match self.hq {
2304            Some(hqs) => {
2305                for _hq in hqs.iter() {
2306                    if &column == _hq {
2307                        return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2308                    }
2309                }
2310            },
2311            None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Your input is invalid."))
2312        }
2313
2314        Ok(())
2315    }
2316
2317    /// checks the inputs for potential sql injection patterns and throws error if they exist.
2318    fn sanitize_columns(columns: &Vec<&str>, hqs: [&'a str; 26]) -> std::result::Result<(), std::io::Error> {
2319        if columns.len() == 1 && columns[0] == "" {
2320            return Ok(());
2321        };
2322
2323        for column in columns.iter() {
2324            for hq in hqs.iter() {
2325                if column == hq {
2326                    return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2327                }
2328            }
2329        }
2330
2331        return Ok(())
2332    }
2333
2334    fn sanitize_inputs(inputs: &Vec<ValueType>, hqs: [&'a str; 26]) -> std::result::Result<(), std::io::Error> {
2335        for input in inputs.iter() {
2336            match input {
2337                ValueType::String(string) | ValueType::Datetime(string) => {
2338                    for hq in hqs.iter() {
2339                        if &string == hq {
2340                            return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2341                        }
2342                    }
2343                },
2344                _ => continue
2345            }
2346        }
2347
2348        return Ok(())
2349    }
2350
2351    fn sanitize_input(&mut self, input: &ValueType) -> std::result::Result<(), std::io::Error> {
2352        match input {
2353            ValueType::String(string) | ValueType::Datetime(string) => {
2354                match self.hq {
2355                    Some(hqs) => {
2356                        for hq in hqs.iter() {
2357                            if &string == hq {
2358                                return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "You cannot run arbitrary queries"))
2359                            }
2360                        }
2361                    },
2362                    None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Your input is invalid."))
2363                }
2364            },
2365            _ => return Ok(())
2366        };
2367
2368        Ok(())
2369    }
2370
2371    fn sanitize_mark(input: &str) -> std::result::Result<(), std::io::Error> {
2372        return match input {
2373            "=" | "<" | ">" | "<=" | ">=" | "!=" | "<>" => Ok(()),
2374            _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=,  >=, != or <>."))
2375        }
2376    }
2377
2378    fn sanitize_str(&mut self, input: &str) -> std::result::Result<(), std::io::Error> {
2379        match self.hq {
2380            Some(hqs) => {
2381                for hq in hqs.iter() {
2382                    if *hq == input {
2383                        return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=,  >=, != or <>."))
2384                    }
2385                }
2386            },
2387            None => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "comparison operators cannot be other than =, <, >, <=,  >=, != or <>."))
2388        }
2389
2390        Ok(())
2391    }
2392}
2393
2394/// Struct that benefits you to create and use schema's.
2395#[derive(Debug, Clone)]
2396pub struct SchemaBuilder {
2397    pub query: String,
2398    pub schema: String,
2399    pub list: Vec<KeywordList>
2400}
2401
2402/// implementations fon SchemaBuilder
2403impl SchemaBuilder {
2404    pub fn create(name: &str) -> std::result::Result<Self, std::io::Error> {
2405        if 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           name.contains("]") ||
2415           name.contains("{") ||
2416           name.contains("}") ||
2417           name.contains(":") ||
2418           name.contains(";") ||
2419           name.contains("'") ||
2420           name.contains("\"") ||
2421           name.contains(",") ||
2422           name.contains(".") {
2423                return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Schame name cannot include these characters: '!', '-', '=', '+', '%', '$', '&', '#', '[', ']', '{', '}', ':', ';', '\"', \"'\", '.', ','"))
2424        }
2425
2426        Ok(Self {
2427            query: format!("CREATE DATABASE {}", name),
2428            schema: name.to_string(),
2429            list: vec![KeywordList::Create]
2430        })
2431    }
2432
2433    pub fn use_another_schema(name: &str) -> std::result::Result<Self, std::io::Error> {
2434        if name.contains("!") ||
2435        name.contains("-") ||
2436        name.contains("=") ||
2437        name.contains("+") ||
2438        name.contains("%") ||
2439        name.contains("$") ||
2440        name.contains("&") ||
2441        name.contains("#") ||
2442        name.contains("[") ||
2443        name.contains("]") ||
2444        name.contains("{") ||
2445        name.contains("}") ||
2446        name.contains(":") ||
2447        name.contains(";") ||
2448        name.contains("'") ||
2449        name.contains("\"") ||
2450        name.contains(",") ||
2451        name.contains(".") {
2452             return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Schame name cannot include these characters: '!', '-', '=', '+', '%', '$', '&', '#', '[', ']', '{', '}', ':', ';', '\"', \"'\", '.', ','"))
2453        }
2454
2455        Ok(Self {
2456            query: format!("USE {}", name),
2457            schema: name.to_string(),
2458            list: vec![KeywordList::Use, KeywordList::Create]
2459        })
2460    }
2461
2462    pub fn if_not_exists(&mut self) -> &mut Self {
2463        match self.list[0] {
2464            KeywordList::Create => (),
2465            KeywordList::Table => (),
2466            _ => panic!("if_not_exists method cannot be used without Create or Table queries")
2467        }
2468
2469        let split_the_query =  self.query.split(" DATABASE ").collect::<Vec<&str>>();
2470        self.query = format!("{} DATABASE IF NOT EXISTS {}", split_the_query[0], split_the_query[1]);
2471
2472        self.list.insert(0, KeywordList::IfNotExist);
2473        self
2474    }
2475
2476    pub fn use_schema(&mut self, name: Option<&str>) -> &mut Self {
2477        match name {
2478            Some(schema_name) => {
2479                self.query = format!("USE {}", schema_name)
2480            },
2481            None => {
2482                self.query = format!("USE {}", self.schema);
2483            }
2484        }
2485
2486        self
2487    }
2488
2489    pub fn finish(&self) -> String {
2490        return format!("{};", self.query)
2491    }
2492}
2493
2494/// Struct that benefits you to create Tables. Currently incomplete thoug.
2495#[derive(Debug, Clone)]
2496pub struct TableBuilder {
2497    pub query: String,
2498    pub name: String,
2499    pub schema: String,
2500    pub all: Vec<String>,
2501}
2502
2503/// Struct that benefits to define a foreign key.
2504#[derive(Debug, Clone)]
2505pub struct ForeignKey {
2506    pub first: ForeignKeyItem,
2507    pub second: ForeignKeyItem,
2508    pub on_delete: Option<ForeignKeyActions>,
2509    pub on_update: Option<ForeignKeyActions>,
2510    pub constraint: Option<String>
2511}
2512
2513/// Struct that benefits you to add a foreign key item to a foreign key.
2514#[derive(Debug, Clone)]
2515pub struct ForeignKeyItem {
2516    pub table: String,
2517    pub column: String
2518}
2519
2520/// implementations for TableBuilder
2521impl TableBuilder {
2522    pub fn create(schema_name: &str, table_name: &str) -> Self {
2523        return Self {
2524            query: format!("CREATE TABLE {} (", table_name),
2525            schema: schema_name.to_string(),
2526            name: table_name.to_string(),
2527            all: vec![]
2528        }
2529    }
2530
2531    pub fn if_not_exists(&mut self) -> &mut Self {
2532        self.query = format!("{}IF NOT EXISTS (", self.query.replace("(", ""));
2533
2534        self
2535    }
2536
2537    pub fn add_column(&mut self, column_name: &str) -> &mut Self {
2538        if self.query.ends_with("(") {
2539            self.query = format!("{}{}", self.query, column_name)
2540        } else {
2541            self.query = format!("{}, {}", self.query, column_name)
2542        }
2543
2544        self
2545    }
2546
2547    pub fn col_type(&mut self, type_name: &str) -> &mut Self {
2548        if self.query.ends_with("(") {
2549            panic!("Cannot add type before defining a column name.")
2550        }
2551
2552        self.query = format!("{} {}", self.query, type_name);
2553
2554        self
2555    }
2556
2557    pub fn null(&mut self) -> &mut Self {
2558        self.query = format!("{} NULL", self.query);
2559
2560        self
2561    }
2562
2563    pub fn not_null(&mut self) -> &mut Self {
2564        self.query = format!("{} NOT NULL", self.query);
2565
2566        self
2567    }
2568
2569    pub fn auto_increment(&mut self) -> &mut Self {
2570        self.query = format!("{} AUTO_INCREMENT", self.query);
2571
2572        self
2573    }
2574
2575    pub fn primary_key(&mut self) -> &mut Self {
2576        if self.query.contains("PRIMARY KEY") {
2577            panic!("A table cannot have two primary keys.")
2578        }
2579
2580        self.query = format!("{} PRIMARY KEY", self.query);
2581
2582        self
2583    }
2584
2585    pub fn default(&mut self, value: ValueType) -> &mut Self {
2586        let split_the_query = self.query.clone();
2587        let split_the_query = split_the_query.split(", ").collect::<Vec<&str>>();
2588
2589        let last_query = split_the_query[split_the_query.len() - 1];
2590
2591        if last_query.contains("INT") || 
2592           last_query.contains("TINYINT") ||
2593           last_query.contains("SMALLINT") ||
2594           last_query.contains("MEDIUMINT") ||
2595           last_query.contains("BIGINT") ||
2596           last_query.contains("BIT") ||
2597           last_query.contains("SERIAL") {
2598            match value {
2599                ValueType::Int8(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2600                ValueType::Int16(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2601                ValueType::Int32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2602                ValueType::Int64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2603                ValueType::Uint8(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2604                ValueType::Uint16(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2605                ValueType::Uint32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2606                ValueType::Uint64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2607                ValueType::Usize(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2608                ValueType::Float32(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2609                ValueType::Float64(int) => self.query = format!("{} DEFAULT {}", self.query, int),
2610                _ => 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.")
2611            }
2612        }
2613
2614        if last_query.contains("BOOL") || 
2615           last_query.contains("BOOLEAN") {
2616            match value {
2617                ValueType::Boolean(boolean) => self.query = format!("{} DEFAULT {}", self.query, boolean),
2618                _ => panic!("If your column type is BOOLEAN, you have to write either true or false.")
2619            }    
2620        }
2621
2622        if last_query.contains("CHAR") ||
2623           last_query.contains("VARCHAR") ||
2624           last_query.contains("TEXT") ||
2625           last_query.contains("TINYTEXT") ||
2626           last_query.contains("MEDIUMTEXT") ||
2627           last_query.contains("LONGTEXT") ||
2628           last_query.contains("BINARY") ||
2629           last_query.contains("VARBINARY") {
2630            match value {
2631                ValueType::String(ref text) => self.query = format!("{} DEFAULT '{}'", self.query, text),
2632                _ => 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.")
2633            }
2634        }
2635
2636        if last_query.contains("DATETIME") ||
2637           last_query.contains("TIMESTAMP") {
2638            match value {
2639                ValueType::Datetime(datetime) => self.query = format!("{} DEFAULT {}", self.query, datetime),
2640                _ => 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.")
2641            }
2642        }
2643
2644        self
2645    }
2646
2647    pub fn unique(&mut self) -> &mut Self {
2648        self.query = format!("{} UNIQUE", self.query);
2649
2650        self
2651    }
2652
2653    pub fn check(&mut self, condition: &str) -> &mut Self {
2654        self.query = format!("{} CHECK({})", self.query, condition);
2655
2656        self
2657    }
2658
2659    pub fn character_set(&mut self, character_set: &str) -> &mut Self {
2660        self.query = format!("{} CHARACTER SET {}", self.query, character_set);
2661
2662        self
2663    }
2664
2665    pub fn foreign_key(&mut self, opts: ForeignKey) -> &mut Self {
2666        if self.query.starts_with("ALTER TABLE") {
2667            match opts.constraint {
2668                Some(constraint) => self.query = format!("{}, ADD CONSTRAINT {} FOREIGN KEY ({})", self.query, constraint, opts.first.column),
2669                None => self.query = format!("{}, ADD FOREIGN KEY ({})", self.query, opts.first.column)
2670            }
2671            
2672        } else {
2673            match opts.constraint {
2674                Some(constraint) => self.query = format!("{}, CONSTRAINT {} FOREIGN KEY ({})", self.query, constraint, opts.first.column),
2675                None => self.query = format!("{}, FOREIGN KEY ({})", self.query, opts.first.column)
2676            }
2677        }
2678
2679        self.query = format!("{} REFERENCES {}({})", self.query, opts.second.table, opts.second.column);
2680
2681        match opts.on_delete {
2682            Some(on_delete_opt) => self.query = format!("{} ON DELETE {}", self.query, on_delete_opt),
2683            None => ()
2684        }
2685
2686        match opts.on_update {
2687            Some(on_update_opt) => self.query = format!("{} ON UPDATE {}", self.query, on_update_opt),
2688            None => ()
2689        }
2690
2691        self
2692    }
2693
2694    pub fn unsigned(&mut self) -> &mut Self {
2695        self.query = format!("{} UNSIGNED", self.query);
2696
2697        self
2698    }
2699
2700    pub fn zerofill(&mut self) -> &mut Self {
2701        self.query = format!("{} ZEROFILL", self.query);
2702
2703        self
2704    }
2705
2706    pub fn enum_sql(&mut self, enum_vec: Vec<&str>) -> &mut Self {
2707        match enum_vec.len() {
2708            0 => panic!("enum_vec argument cannot be an empty vector"),
2709            _ => ()
2710        }
2711        
2712        self.query = format!("{} ENUM(", self.query);
2713
2714        let length_of_enum_vec = enum_vec.len();
2715        for (index, item) in enum_vec.into_iter().enumerate() {
2716            if index + 1 == length_of_enum_vec {
2717                self.query = format!("{}'{}'", self.query, item)
2718            } else {
2719                self.query = format!("{}'{}', ", self.query, item)
2720            }
2721        }
2722
2723        self
2724    }
2725
2726    pub fn generated_always(&mut self, condition: &str) -> &mut Self {
2727        self.query = format!("{} GENERATED ALWAYS AS {}", self.query, condition);
2728
2729        self
2730    }
2731
2732    pub fn virtual_sql(&mut self) -> &mut Self {
2733        self.query = format!("{} VIRTUAL", self.query);
2734
2735        self
2736    }
2737
2738    pub fn stored(&mut self) -> &mut Self {
2739        self.query = format!("{} STORED", self.query);
2740
2741        self
2742    }
2743
2744    pub fn spatial(&mut self) -> &mut Self {
2745        self.query = format!("{} SPATIAL", self.query);
2746
2747        self
2748    }
2749
2750    pub fn generated(&mut self) -> &mut Self {
2751        self.query = format!("{} GENERATED", self.query);
2752
2753        self
2754    }
2755
2756    pub fn index(&mut self, indexes: Vec<&str>) -> &mut Self {
2757        let length_of_indexes = indexes.len();
2758
2759        match length_of_indexes {
2760            0 => panic!("There is no index here."),
2761            1 => self.query = format!("{}, INDEX({})", self.query, indexes[0]),
2762            _ => {
2763                for (i, index) in indexes.into_iter().enumerate() {
2764                    if i + 1 == length_of_indexes {
2765                        self.query = format!("{}{}", self.query, index);
2766
2767                        continue;
2768                    }
2769
2770                    if i == 0 {
2771                        self.query = format!("{}, INDEX ({}, ", self.query, index);
2772
2773                        continue;
2774                    }
2775
2776                    self.query = format!("{}{}, ", self.query, index)
2777                }
2778            }
2779        }
2780
2781        self
2782    }
2783
2784    pub fn comment(&mut self, comment: &str) -> &mut Self {
2785        self.query = format!("{} COMMENT '{}'", self.query, comment);
2786
2787        self
2788    }
2789
2790    pub fn default_on_null(&mut self, value: ValueType) -> &mut Self {
2791        match value {
2792            ValueType::String(text) => self.query = format!("{} DEFAULT {} ON NULL", self.query, text),
2793            _ => self.query = format!("{} DEFAULT {} ON NULL", self.query, value),
2794        }
2795
2796        self
2797    }
2798
2799    pub fn invisible(&mut self) -> &mut Self {
2800        self.query = format!("{} INVISIBLE", self.query);
2801
2802        self
2803    }
2804
2805    pub fn custom_query(&mut self, query: &str) -> &mut Self {
2806        self.query = format!("{} {}", self.query, query);
2807
2808        self
2809    }
2810
2811    pub fn finish(&mut self) -> String {
2812        return format!("{});", self.query)
2813    }
2814}
2815
2816/// KeywordList enum. It helps to syntactically correcting the queries. 
2817#[derive(Debug, Clone, PartialEq)]
2818pub enum KeywordList {
2819    Select, Update, Delete, Insert, Count, Table, Where, Or, And, Set, 
2820    Finish, OrderBy, GroupBy, Having, Like, Limit, Offset, IfNotExist, Create, Use, WhereIn, 
2821    WhereNotIn, AndIn, AndNotIn, OrIn, OrNotIn, JsonExtract, JsonContains, NotJsonContains, JsonArrayAppend, JsonRemove, JsonSet, JsonReplace, 
2822    Field, Union, UnionAll, Timezone, GlobalTimezone, InnerJoin, LeftJoin
2823}
2824
2825/// QueryType enum. It helps to detect the type of a query with more optimized way when is needed.
2826#[derive(Debug, Clone)]
2827pub enum QueryType {
2828    Select, Update, Delete, Insert, Null, Create, Count
2829}
2830
2831/// ValueType enum. It benefits to detect and format the value with optimized way when you have to work with exact column values. 
2832#[derive(Debug, Clone)]
2833pub enum ValueType {
2834    String(String), Datetime(String), Null, Boolean(bool), Int32(i32), Int16(i16), Int8(i8), Int64(i64), Int128(i128),
2835    Uint8(u8), Uint16(u16), Uint32(u32), Uint64(u64), Usize(usize), Float32(f32), Float64(f64),
2836    EpochTime(i64), JsonString(String)
2837}
2838
2839impl std::fmt::Display for ValueType {
2840    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2841        match self {
2842            ValueType::String(string) => write!(f, "'{}'", string),
2843            ValueType::JsonString(string) => write!(f, "\"{}\"", string),
2844            ValueType::Datetime(datetime) => match datetime.as_str() {
2845                "CURRENT_TIMESTAMP" | "UNIX_TIMESTAMP" | "CURRENT_DATE" | "CURRENT_TIME" | "NOW()" | "CURDATE()" | "CURTIME()" => write!(f, "{}", datetime),
2846                _ => write!(f, "'{}'", datetime)
2847            },
2848            ValueType::Null => write!(f, "NULL"),
2849            ValueType::Boolean(val) => write!(f, "{}", val),
2850            ValueType::Int8(val) => write!(f, "{}", val),
2851            ValueType::Int16(val) => write!(f, "{}", val),
2852            ValueType::Int32(val) => write!(f, "{}", val),
2853            ValueType::Int64(val) => write!(f, "{}", val),
2854            ValueType::Int128(val) => write!(f, "{}", val),
2855            ValueType::Usize(val) => write!(f, "{}", val),
2856            ValueType::Uint8(val) => write!(f, "{}", val),
2857            ValueType::Uint16(val) => write!(f, "{}", val),
2858            ValueType::Uint32(val) => write!(f, "{}", val),
2859            ValueType::Uint64(val) => write!(f, "{}", val),
2860            ValueType::Float32(val) => write!(f, "{}", val),
2861            ValueType::Float64(val) => write!(f, "{}", val),
2862            ValueType::EpochTime(val) => write!(f, "FROM_UNIXTIME({})", val),
2863        }
2864    }
2865}
2866
2867impl From<String> for ValueType { fn from(value: String) -> Self { ValueType::String(value) } }
2868impl From<bool> for ValueType { fn from(value: bool) -> Self { ValueType::Boolean(value) } }
2869impl From<i8> for ValueType { fn from(value: i8) -> Self { ValueType::Int8(value) } }
2870impl From<i16> for ValueType { fn from(value: i16) -> Self { ValueType::Int16(value) } }
2871impl From<i32> for ValueType { fn from(value: i32) -> Self { ValueType::Int32(value) } }
2872impl From<i64> for ValueType { fn from(value: i64) -> Self { ValueType::Int64(value) } }
2873impl From<i128> for ValueType { fn from(value: i128) -> Self { ValueType::Int128(value) } }
2874impl From<usize> for ValueType { fn from(value: usize) -> Self { ValueType::Usize(value) } }
2875impl From<u8> for ValueType { fn from(value: u8) -> Self { ValueType::Uint8(value) } }
2876impl From<u16> for ValueType { fn from(value: u16) -> Self { ValueType::Uint16(value) } }
2877impl From<u32> for ValueType { fn from(value: u32) -> Self { ValueType::Uint32(value) } }
2878impl From<u64> for ValueType { fn from(value: u64) -> Self { ValueType::Uint64(value) } }
2879impl From<f32> for ValueType { fn from(value: f32) -> Self { ValueType::Float32(value) } }
2880impl From<f64> for ValueType { fn from(value: f64) -> Self { ValueType::Float64(value) } }
2881
2882
2883impl Into<String> for ValueType {
2884    fn into(self) -> String {
2885        match self {
2886            ValueType::String(text) => text,
2887            ValueType::Datetime(datetime) => datetime,
2888            _ => panic!("you cannot convert a ValueType to string unless it's not a String or Datetime variant.")
2889        }
2890    }
2891}
2892
2893impl Into<bool> for ValueType {
2894    fn into(self) -> bool {
2895        match self {
2896            ValueType::Boolean(val) => val,
2897            ValueType::String(text) => match text.as_str() {
2898                "false" | "" | "\0" | "0" => false,
2899                _ => true,
2900            }
2901            ValueType::Null => false,
2902            ValueType::Int8(val) => match val == 0 {
2903                false => true,
2904                true => false
2905            },
2906            ValueType::Int16(val) => match val == 0 {
2907                false => true,
2908                true => false
2909            },
2910            ValueType::Int32(val) => match val == 0 {
2911                false => true,
2912                true => false
2913            },
2914            ValueType::Int64(val) => match val == 0 {
2915                false => true,
2916                true => false
2917            },
2918            ValueType::Int128(val) => match val == 0 {
2919                false => true,
2920                true => false
2921            },
2922            ValueType::Uint8(val) => match val == 0 {
2923                false => true,
2924                true => false
2925            },
2926            ValueType::Uint16(val) => match val == 0 {
2927                false => true,
2928                true => false
2929            },
2930            ValueType::Uint32(val) => match val == 0 {
2931                false => true,
2932                true => false
2933            },
2934            ValueType::Uint64(val) => match val == 0 {
2935                false => true,
2936                true => false
2937            },
2938            ValueType::Float32(val) => match val == 0.0 {
2939                false => true,
2940                true => false
2941            },
2942            ValueType::Float64(val) => match val == 0.0 {
2943                false => true,
2944                true => false
2945            },
2946            _ => panic!("invalid conversion")
2947        }
2948    }
2949}
2950
2951impl Into<f32> for ValueType {
2952    fn into(self) -> f32 {
2953        match self {
2954            ValueType::Float32(num) => num,
2955            ValueType::Float64(num) => num as f32,
2956            _ => panic!("invalid conversion")
2957        }
2958    }
2959}
2960
2961impl Into<f64> for ValueType {
2962    fn into(self) -> f64 {
2963        match self {
2964            ValueType::Float32(num) => num as f64,
2965            ValueType::Float64(num) => num,
2966            _ => panic!("invalid conversion")
2967        }
2968    }
2969}
2970
2971impl Into<i8> for ValueType {
2972    fn into(self) -> i8 {
2973        match self {
2974            ValueType::Int8(num) => num,
2975            ValueType::Int16(num) => match num > 128 || num < -128 {
2976                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2977                false => num as i8
2978            },
2979            ValueType::Int32(num) => match num > 128 || num < -128 {
2980                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2981                false => num as i8
2982            },
2983            ValueType::Int64(num) => match num > 128 || num < -128 {
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 i8
2986            },
2987            ValueType::Int128(num) => match num > 128 || num < -128 {
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 i8
2990            }
2991            ValueType::Uint8(num) => match num > 128 {
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 i8
2994            },
2995            ValueType::Uint16(num) => match num > 128 {
2996                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
2997                false => num as i8
2998            },
2999            ValueType::Uint32(num) => match num > 128 {
3000                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3001                false => num as i8
3002            },
3003            ValueType::Usize(num) => match num > 128 {
3004                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3005                false => num as i8
3006            },
3007            ValueType::Uint64(num) => match num > 128 {
3008                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3009                false => num as i8
3010            },
3011            _ => panic!("you cannot convert non numeric values into numeric ones.")
3012        }
3013    }
3014}
3015
3016impl Into<i16> for ValueType {
3017    fn into(self) -> i16 {
3018        match self {
3019            ValueType::Int8(num) => num as i16,
3020            ValueType::Int16(num) => num,
3021            ValueType::Int32(num) => match num > 32_768 || num < -32_768 {
3022                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3023                false => num as i16
3024            },
3025            ValueType::Int64(num) => match num > 32_768 || num < -32_768 {
3026                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3027                false => num as i16
3028            },
3029            ValueType::Int128(num) => match num > 32_768 || num < -32_768 {
3030                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3031                false => num as i16
3032            }
3033            ValueType::Uint8(num) => num as i16,
3034            ValueType::Uint16(num) => match num > 32_768 {
3035                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3036                false => num as i16
3037            },
3038            ValueType::Uint32(num) => match num > 32_768 {
3039                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3040                false => num as i16
3041            },
3042            ValueType::Usize(num) => match num > 32_768 {
3043                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3044                false => num as i16
3045            },
3046            ValueType::Uint64(num) => match num > 32_768 {
3047                true => panic!("you cannot convert i16's into a value which is bigger than the capacity of 32 bit values."),
3048                false => num as i16
3049            },
3050            _ => panic!("you cannot convert non numeric values into numeric ones.")
3051        }
3052    }
3053}
3054
3055impl Into<i32> for ValueType {
3056    fn into(self) -> i32 {
3057        match self {
3058            ValueType::Int8(num) => num as i32,
3059            ValueType::Int16(num) => num as i32,
3060            ValueType::Int32(num) => num,
3061            ValueType::Int64(num) => match num > 2_147_483_647 || num < -2_147_483_647 {
3062                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
3063                false => num as i32
3064            },
3065            ValueType::Int128(num) => match num > 2_147_483_647 || num < -2_147_483_647 {
3066                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
3067                false => num as i32
3068            }
3069            ValueType::Uint8(num) => num as i32,
3070            ValueType::Uint16(num) => num as i32,
3071            ValueType::Uint32(num) => match num > 2_147_483_647 {
3072                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
3073                false => num as i32
3074            },
3075            ValueType::Usize(num) => match num > 2_147_483_647 {
3076                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
3077                false => num as i32
3078            },
3079            ValueType::Uint64(num) => match num > 2_147_483_647 {
3080                true => panic!("you cannot convert i32's into a value which is bigger than the capacity of 32 bit values."),
3081                false => num as i32
3082            }
3083            _ => panic!("you cannot convert non numeric values into numeric ones.")
3084        }
3085    }
3086}
3087
3088impl Into<i64> for ValueType {
3089    fn into(self) -> i64 {
3090        match self {
3091            ValueType::EpochTime(epoch) => epoch as i64,
3092            ValueType::Int8(num) => num as i64,
3093            ValueType::Int16(num) => num as i64,
3094            ValueType::Int32(num) => num as i64,
3095            ValueType::Int64(num) => num,
3096            ValueType::Usize(num) => num as i64,
3097            ValueType::Uint8(num) => num as i64,
3098            ValueType::Uint16(num) => num as i64,
3099            ValueType::Uint32(num) => num as i64,
3100            ValueType::Uint64(num) => num as i64,
3101            _ => panic!("you cannot convert non numeric values into numeric ones.")
3102        }
3103    }
3104}
3105
3106impl Into<u8> for ValueType {
3107    fn into(self) -> u8 {
3108        match self {
3109            ValueType::Uint8(num) => num,
3110            ValueType::Uint16(num) => match num > 255 {
3111                true => panic!("you cannot convert u16's if it's value is bigger than capacity of 8 bit values"),
3112                false => num as u8
3113            },
3114            ValueType::Uint32(num) => match num > 255 {
3115                true => panic!("you cannot convert u32's if it's value is bigger than capacity of 8 bit values"),
3116                false => num as u8
3117            },
3118            ValueType::Uint64(num) => match num > 255 {
3119                true => panic!("you cannot convert u64's if it's value is bigger than capacity of 8 bit values"),
3120                false => num as u8
3121            },
3122            ValueType::Usize(num) => match num > 255 {
3123                true => panic!("you cannot convert usizes if it's value is bigger than capacity of 8 bit values"),
3124                false => num as u8
3125            },
3126            ValueType::Int8(num) => match num < 0 {
3127                true => panic!("you cannot convert i8's if it's value is lower than 0"),
3128                false => num as u8
3129            },
3130            ValueType::Int16(num) => match num < 0 || num > 255 {
3131                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."),
3132                false => num as u8
3133            },
3134            ValueType::Int32(num) => match num < 0 || num > 255 {
3135                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."),
3136                false => num as u8
3137            },
3138            ValueType::Int64(num) => match num < 0 || num > 255 {
3139                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."),
3140                false => num as u8
3141            },
3142            ValueType::Int128(num) => match num < 0 || num > 255 {
3143                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."),
3144                false => num as u8
3145            }
3146            _ => panic!("you cannot convert non numeric values into numeric ones.")
3147        }
3148    }
3149}
3150
3151impl Into<u16> for ValueType {
3152    fn into(self) -> u16 {
3153        match self {
3154            ValueType::Uint8(num) => num as u16,
3155            ValueType::Uint16(num) => num,
3156            ValueType::Uint32(num) => match num > 65_535 {
3157                true => panic!("you cannot convert u32's if it's value is bigger than capacity of 32 bit values"),
3158                false => num as u16
3159            },
3160            ValueType::Uint64(num) => match num > 65_535 {
3161                true => panic!("you cannot convert u64's if it's value is bigger than capacity of 32 bit values"),
3162                false => num as u16
3163            },
3164            ValueType::Usize(num) => match num > 65_535 {
3165                true => panic!("you cannot convert usizes if it's value is bigger than capacity of 32 bit values"),
3166                false => num as u16
3167            },
3168            ValueType::Int8(num) => match num < 0 {
3169                true => panic!("you cannot convert i8's if it's value is lower than 0"),
3170                false => num as u16
3171            },
3172            ValueType::Int16(num) => match num < 0 {
3173                true => panic!("you cannot convert i16's if it's value is lower than 0"),
3174                false => num as u16
3175            },
3176            ValueType::Int32(num) => match num < 0 || num > 65_535 {
3177                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."),
3178                false => num as u16
3179            },
3180            ValueType::Int64(num) => match num < 0 || num > 65_535 {
3181                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."),
3182                false => num as u16
3183            },
3184            ValueType::Int128(num) => match num < 0 || num > 65_535 {
3185                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."),
3186                false => num as u16
3187            }
3188            _ => panic!("you cannot convert non numeric values into numeric ones.")
3189        }
3190    }
3191}
3192
3193impl Into<u32> for ValueType {
3194    fn into(self) -> u32 {
3195        match self {
3196            ValueType::Uint8(num) => num as u32,
3197            ValueType::Uint16(num) => num as u32,
3198            ValueType::Uint32(num) => num,
3199            ValueType::Uint64(num) => match num > 4_294_967_295 {
3200                true => panic!("you cannot convert u64's if it's value is bigger than capacity of 32 bit values"),
3201                false => num as u32
3202            },
3203            ValueType::Usize(num) => match num > 4_294_967_295 {
3204                true => panic!("you cannot convert usizes if it's value is bigger than capacity of 32 bit values"),
3205                false => num as u32
3206            },
3207            ValueType::Int8(num) => match num < 0 {
3208                true => panic!("you cannot convert i8's if it's value is lower than 0"),
3209                false => num as u32
3210            },
3211            ValueType::Int16(num) => match num < 0 {
3212                true => panic!("you cannot convert i16's if it's value is lower than 0"),
3213                false => num as u32
3214            },
3215            ValueType::Int32(num) => match num < 0 {
3216                true => panic!("you cannot convert i32's if it's value is lower than 0"),
3217                false => num as u32
3218            },
3219            ValueType::Int64(num) => match num < 0 || num > 4_294_967_295 {
3220                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."),
3221                false => num as u32
3222            },
3223            ValueType::Int128(num) => match num < 0 || num > 4_294_967_295 {
3224                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."),
3225                false => num as u32
3226            }
3227            _ => panic!("you cannot convert non numeric values into numeric ones.")
3228        }
3229    }
3230}
3231
3232impl Into<u64> for ValueType {
3233    fn into(self) -> u64 {
3234        match self {
3235            ValueType::Usize(num) => num as u64,
3236            ValueType::Uint8(num) => num as u64,
3237            ValueType::Uint16(num) => num as u64,
3238            ValueType::Uint32(num) => num as u64,
3239            ValueType::Uint64(num) => num,
3240            ValueType::Int8(num) => match num < 0 {
3241                true => panic!("you cannot turn a negative value into u64"),
3242                false => num as u64
3243            },
3244            ValueType::Int16(num) => match num < 0 {
3245                true => panic!("you cannot turn a negative value into u64"),
3246                false => num as u64
3247            },
3248            ValueType::Int32(num) => match num < 0 {
3249                true => panic!("you cannot turn a negative value into u64"),
3250                false => num as u64
3251            },
3252            ValueType::Int64(num) => match num < 0 {
3253                true => panic!("you cannot turn a negative value into u64"),
3254                false => num as u64
3255            },
3256            ValueType::Int128(num) => match num < 0 {
3257                true => panic!("you cannot turn a negative value into u64"),
3258                false => num as u64
3259            },
3260            _ => panic!("you cannot convert non numeric values into numeric ones.")
3261        }
3262    }
3263}
3264
3265impl Into<usize> for ValueType {
3266    fn into(self) -> usize {
3267        match self {
3268            ValueType::Int8(num) => match num < 0 {
3269                true => panic!("you cannot convert negative numbers to usize"),
3270                false => num as usize
3271            },
3272            ValueType::Int16(num) => match num < 0 {
3273                true => panic!("you cannot convert negative numbers to usize"),
3274                false => num as usize
3275            },
3276            ValueType::Int32(num) => match num < 0 {
3277                true => panic!("you cannot convert negative numbers to usize"),
3278                false => num as usize
3279            },
3280            ValueType::Int64(num) => match num < 0 {
3281                true => panic!("you cannot convert negative numbers to usize"),
3282                false => num as usize
3283            },
3284            ValueType::Int128(num) => match num < 0 {
3285                true => panic!("you cannot convert negative numbers to usize"),
3286                false => num as usize
3287            },
3288            ValueType::Usize(num) => num,
3289            ValueType::Uint8(num) => num as usize,
3290            ValueType::Uint16(num) => num as usize,
3291            ValueType::Uint32(num) => num as usize,
3292            ValueType::Uint64(num) => num as usize,
3293            _ => panic!("you cannot convert non numeric values into numeric ones.")
3294        }
3295    }
3296}
3297
3298/// Enum that benefits you to add json values to structs. They can be used with json functions.
3299/// That variants represents that kind of json values:
3300#[derive(Debug, Clone)]
3301pub enum JsonValue<'a> {
3302    /// 
3303    /// Example Value: ["hello", 21, "again"]
3304    /// 
3305    Array(&'a Vec<ValueType>), 
3306    
3307    /// 
3308    /// Example Value: {"name": "necdet", "message": "hello", "id": 1}
3309    /// 
3310    Object(&'a Vec<(&'a str, &'a ValueType)>), 
3311    
3312    ///
3313    /// example value: [{"name": "necdet", "message": "hello", "id": 1}, {"name": "kemal", "message": "hi", "id": 2}]
3314    /// 
3315    ObjectArray(&'a Vec<Vec<(&'a str, &'a ValueType)>>), 
3316    
3317    /// It's same with `ValueType` enums, just for simply passing it to that enum.
3318    Initial(&'a ValueType), 
3319
3320    /// 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.
3321    MysqlJsonObject(&'a Vec<(&'a str, &'a ValueType)>)
3322}
3323
3324impl <'a>std::fmt::Display for JsonValue<'a> {
3325    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3326        match self {
3327            JsonValue::Array(values) => {
3328                let mut json_str = "[".to_string();
3329
3330                for (index, value) in values.iter().enumerate() {
3331                    if index == 0 {
3332                        json_str = format!("{}{}", json_str, value)
3333                    } else {
3334                        json_str = format!("{}, {}", json_str, value)
3335                    }
3336                }
3337
3338                json_str = format!("{}]", json_str);
3339
3340                write!(f, "{}", json_str)
3341            },
3342            JsonValue::Object(props) => {
3343                let mut json_str = "{".to_string();
3344
3345                for (index, value) in props.iter().enumerate() {
3346                    if index == 0 {
3347                        json_str = format!("{}\"{}\": {}", json_str, value.0, value.1)
3348                    } else {
3349                        json_str = format!("{}, \"{}\": {}", json_str, value.0, value.1)
3350                    }
3351                }
3352
3353                json_str = format!("{}}}", json_str);
3354
3355                write!(f, "{}", json_str)
3356            },
3357            JsonValue::MysqlJsonObject(props) => {
3358                let mut json_str = "JSON_OBJECT(".to_string();
3359
3360                for (index, value) in props.iter().enumerate() {
3361                    if index == 0 {
3362                        json_str = format!("{}'{}', {}", json_str, value.0, value.1)
3363                    } else {
3364                        json_str = format!("{}, '{}', {}", json_str, value.0, value.1)
3365                    }
3366                }
3367
3368                json_str = format!("{})", json_str);
3369
3370                write!(f, "{}", json_str)
3371            },
3372            JsonValue::ObjectArray(array) => {
3373                let mut json_str = "[".to_string();
3374
3375                for (index1, object) in array.into_iter().enumerate() {
3376                    let mut object_str = "{".to_string();
3377
3378                    for (index2, property) in object.into_iter().enumerate() {
3379                        if index2 == 0 {
3380                            object_str = format!("{}\"{}\": {}", object_str, property.0, property.1)
3381                        } else {
3382                            object_str = format!("{}, \"{}\": {}", object_str, property.0, property.1)
3383                        }
3384                    }
3385
3386                    object_str = format!("{}}}", object_str);
3387
3388                    if index1 == 0 {
3389                        json_str = format!("{}{}", json_str, object_str)
3390                    } else {
3391                        json_str = format!("{}, {}", json_str, object_str)
3392                    }
3393                }
3394
3395                write!(f, "{}]", json_str)
3396            },
3397            JsonValue::Initial(value) => write!(f, "{}", value.to_string())
3398        }
3399    }
3400}
3401
3402/// Timezones with Unix Timezone format, Can be used for setting timezone manually.
3403/// It covers european, russian, north american, south american, arabic countries. In next releases, we'll cover other african and asian timezones. 
3404#[derive(Debug, Clone)]
3405pub enum Timezone {
3406    System, Istanbul, Moscow, Kaliningrad, Samara, Ekaterinburg, Omsk, Krasnoyarsk, Irkutsk, Yakutsk,
3407    Vladivostok, Magadan, Kamchatka, Shanghai, London, Paris, Berlin, Madrid, Rome, Amsterdam, Stockholm, Oslo,
3408    Helsinki, Athens, NewYork, Chicago, Denver, LosAngeles, Anchorage, Honolulu, PuertoRico, Riyadh, Dubai, Qatar,
3409    Kuwait, Bahrain, Muscat, Aden, Baghdad, Amman, Beirut, Damascus, Gaza, Hebron, Cairo, Khartoum, Tripoli,
3410    Tunis, BuenosAires, LaPaz, SaoPaulo, Manaus, Recife, Cuiaba, PortoVelho, Santiago, Easter, Bogota, Guayaquil,
3411    Galapagos, Guyana, Asuncion, Lima, Paramaribo, Montevideo, Caracas, StJohns, Halifax, Toronto, Winnipeg,
3412    Edmonton, Vancouver, WhiteHorse, MexicoCity, Mazatlan, Chihuahua, Tijuana, Cancun, Belize, CostaRica, ElSalvador,
3413    Guatemala, Tegucigalpa, Managua, Panama, Apia, Auckland, Bougainville, Chatham, Efate, Enderbury, Fakaofo,
3414    Fiji, Funafuti, Gambier, Guadalcanal, Guam, Johnston, Kanton, Kiritimati, Kosrae, Kwajalein, Majuro, Marquesas,
3415    Midway, Nauru, Niue, Norfolk, Noumea, PagoPago, Palau, Pitcairn, Pohnpei, PortMoresby, Saipan, Rarotonga, Tahiti,
3416    Tarawa, Truk, Wake, Wallis, Yap, Tongatapu
3417}
3418
3419impl std::fmt::Display for Timezone {
3420    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3421        match self {
3422            Timezone::System => write!(f, "SYSTEM"), Timezone::Istanbul => write!(f, "Europe/Istanbul"), Timezone::Moscow => write!(f, "Europe/Moscow"),
3423            Timezone::Kaliningrad => write!(f, "Europe/Kaliningrad"), Timezone::Samara => write!(f, "Europe/Samara"), Timezone::Ekaterinburg => write!(f, "Asia/Yekaterinburg"),
3424            Timezone::Omsk => write!(f, "Asia/Omsk"), Timezone::Krasnoyarsk => write!(f, "Asia/Krasnoyarsk"), Timezone::Irkutsk => write!(f, "Asia/Irkutsk"),
3425            Timezone::Yakutsk => write!(f, "Asia/Yakutsk"), Timezone::Vladivostok => write!(f, "Asia/Vladivostok"), Timezone::Magadan => write!(f, "Asia/Magadan"),
3426            Timezone::Kamchatka => write!(f, "Asia/Kamchatka"), Timezone::Shanghai => write!(f, "Asia/Shanghai"), Timezone::London => write!(f, "Europe/London"),
3427            Timezone::Paris => write!(f, "Europe/Paris"), Timezone::Berlin => write!(f, "Europe/Berlin"), Timezone::Madrid => write!(f, "Europe/Madrid"),
3428            Timezone::Rome => write!(f, "Europe/Rome"), Timezone::Amsterdam => write!(f, "Europe/Amsterdam"), Timezone::Stockholm => write!(f, "Europe/Stockholm"),
3429            Timezone::Oslo => write!(f, "Europe/Oslo"), Timezone::Helsinki => write!(f, "Europe/Helsinki"), Timezone::Athens => write!(f, "Europe/Athens"),
3430            Timezone::NewYork => write!(f, "America/New_York"), Timezone::Chicago => write!(f, "America/Chicago"), Timezone::Denver => write!(f, "America/Denver"),
3431            Timezone::LosAngeles => write!(f, "America/Los_Angeles"), Timezone::Anchorage => write!(f, "America/Anchorage"), Timezone::Honolulu => write!(f, "Pacific/Honolulu"),
3432            Timezone::PuertoRico => write!(f, "America/Puerto_Rico"), Timezone::Riyadh => write!(f, "Asia/Riyadh"), Timezone::Dubai => write!(f, "Asia/Dubai"),
3433            Timezone::Qatar => write!(f, "Asia/Qatar"), Timezone::Kuwait => write!(f, "Asia/Kuwait"), Timezone::Bahrain => write!(f, "Asia/Bahrain"), Timezone::Muscat => write!(f, "Asia/Muscat"),
3434            Timezone::Aden => write!(f, "Asia/Aden"), Timezone::Baghdad => write!(f, "Asia/Baghdad"), Timezone::Amman => write!(f, "Asia/Amman"), Timezone::Beirut => write!(f, "Asia/Beirut"),
3435            Timezone::Damascus => write!(f, "Asia/Damascus"), Timezone::Gaza => write!(f, "Asia/Gaza"), Timezone::Hebron => write!(f, "Asia/Hebron"), Timezone::Cairo => write!(f, "Africa/Cairo"),
3436            Timezone::Khartoum => write!(f, "Africa/Khartoum"), Timezone::Tripoli => write!(f, "Africa/Tripoli"), Timezone::Tunis => write!(f, "Africa/Tunis"),
3437            Timezone::BuenosAires => write!(f, "America/Argentina/Buenos_Aires"), Timezone::LaPaz => write!(f, "America/La_Paz"), Timezone::SaoPaulo => write!(f, "America/Sao_Paulo"),
3438            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"),
3439            Timezone::Santiago => write!(f, "America/Santiago"), Timezone::Easter => write!(f, "Pacific/Easter"), Timezone::Bogota => write!(f, "America/Bogota"), Timezone::Guayaquil => write!(f, "America/Guayaquil"),
3440            Timezone::Galapagos => write!(f, "Pacific/Galapagos"), Timezone::Guyana => write!(f, "America/Guyana"), Timezone::Asuncion => write!(f, "America/Asuncion"), Timezone::Lima => write!(f, "America/Lima"),
3441            Timezone::Paramaribo => write!(f, "America/Paramaribo"), Timezone::Montevideo => write!(f, "America/Montevideo"), Timezone::Caracas => write!(f, "America/Caracas"),
3442            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"),
3443            Timezone::Edmonton => write!(f, "America/Edmonton"), Timezone::Vancouver => write!(f, "America/Vancouver"), Timezone::WhiteHorse => write!(f, "America/Whitehorse"),
3444            Timezone::MexicoCity => write!(f, "America/Mexico_City"), Timezone::Mazatlan => write!(f, "America/Mazatlan"), Timezone::Chihuahua => write!(f, "America/Chihuahua"),
3445            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"),
3446            Timezone::ElSalvador => write!(f, "America/El_Salvador"), Timezone::Guatemala => write!(f, "America/Guatemala"), Timezone::Tegucigalpa => write!(f, "America/Tegucigalpa"),
3447            Timezone::Managua => write!(f, "America/Managua"), Timezone::Panama => write!(f, "America/Panama"), Timezone::Apia => write!(f, "Pacific/Apia"),
3448            Timezone::Auckland => write!(f, "Pacific/Auckland"), Timezone::Bougainville => write!(f, "Pacific/Bougainville"), Timezone::Chatham => write!(f, "Pacific/Chatham"),
3449            Timezone::Efate => write!(f, "Pacific/Efate"), Timezone::Enderbury => write!(f, "Pacific/Enderbury"), Timezone::Tongatapu => write!(f, "Pacific/Tongatapu"),
3450            Timezone::Fakaofo => write!(f, "Pacific/Fakaofo"), Timezone::Fiji => write!(f, "Pacific/Fiji"), Timezone::Funafuti => write!(f, "Pacific/Funafuti"),
3451            Timezone::Gambier => write!(f, "Pacific/Gambier"), Timezone::Guadalcanal => write!(f, "Pacific/Guadalcanal"), Timezone::Guam => write!(f, "Pacific/Guam"),
3452            Timezone::Johnston => write!(f, "Pacific/Johnston"), Timezone::Kanton => write!(f, "Pacific/Kanton"), Timezone::Kiritimati => write!(f, "Pacific/Kiritimati"),
3453            Timezone::Kosrae => write!(f, "Pacific/Kosrae"), Timezone::Majuro => write!(f, "Pacific/Majuro"), Timezone::Kwajalein => write!(f, "Pacific/Kwajalein"),
3454            Timezone::Midway => write!(f, "Pacific/Midway"), Timezone::Nauru => write!(f, "Pacific/Nauru"), Timezone::Niue => write!(f, "Pacific/Niue"),
3455            Timezone::Marquesas => write!(f, "Pacific/Marquesas"), Timezone::Norfolk => write!(f, "Pacific/Norfolk"), Timezone::PagoPago => write!(f, "Pacific/Pago_Pago"),
3456            Timezone::Noumea => write!(f, "Pacific/Noumea"), Timezone::Palau => write!(f, "Pacific/Palau"), Timezone::Pitcairn => write!(f, "Pacific/Pitcairn"),
3457            Timezone::Pohnpei => write!(f, "Pacific/Pohnpei"), Timezone::PortMoresby => write!(f, "Pacific/Port_Moresby"), Timezone::Rarotonga => write!(f, "Pacific/Rarotonga"),
3458            Timezone::Tahiti => write!(f, "Pacific/Tahiti"), Timezone::Tarawa => write!(f, "Pacific/Tarawa"), Timezone::Saipan => write!(f, "Pacific/Saipan"),
3459            Timezone::Truk => write!(f, "Pacific/Truk"), Timezone::Wake => write!(f, "Pacific/Wake"), Timezone::Wallis => write!(f, "Pacific/Wallis"),
3460            Timezone::Yap => write!(f, "Pacific/Yap")
3461        }
3462    }
3463}
3464
3465/// Enum that benefits you to define what you want with a foreign key.
3466#[derive(Debug, Clone)]
3467pub enum ForeignKeyActions {
3468    Cascade, Restrict, SetNull, NoAction, SetDefault
3469}
3470
3471impl std::fmt::Display for ForeignKeyActions {
3472    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3473        match self {
3474            &ForeignKeyActions::Cascade => write!(f, "CASCADE"),
3475            &ForeignKeyActions::NoAction => write!(f, "NO ACTION"),
3476            &ForeignKeyActions::Restrict => write!(f, "RESTRICT"),
3477            &ForeignKeyActions::SetNull => write!(f, "SET NULL"),
3478            &ForeignKeyActions::SetDefault => write!(f, "SET DEFAULT")
3479        }
3480    }
3481}
3482
3483#[cfg(test)]
3484mod test {
3485    use super::*;
3486
3487    #[test]
3488    pub fn test_schema_query_declarative(){
3489        let schema = SchemaBuilder::create("blog_website").unwrap().if_not_exists().finish();
3490
3491        assert_eq!("CREATE DATABASE IF NOT EXISTS blog_website;", schema);
3492    }
3493
3494    #[test]
3495    pub fn test_schema_query_imperative(){
3496        let mut schema = SchemaBuilder::create("blog_website").unwrap();
3497        schema.if_not_exists();
3498        let schema_query = schema.finish();
3499
3500        assert_eq!("CREATE DATABASE IF NOT EXISTS blog_website;", schema_query);
3501    }
3502
3503    #[test]
3504    pub fn test_use_another_schema(){
3505        let schema = SchemaBuilder::use_another_schema("chat_website").unwrap().finish();
3506
3507        assert_eq!("USE chat_website;", schema);
3508    }
3509
3510    #[test]
3511    pub fn test_insert_query(){
3512        let columns = vec!["title", "author", "description"];
3513        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())];
3514    
3515        let insert_query = QueryBuilder::insert(columns, values).unwrap().table("blogs").finish();
3516
3517        println!("{}", insert_query);
3518        assert_eq!("INSERT INTO blogs (title, author, description) VALUES ('What's Up?', 'John Doe', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');".to_string(), 
3519                    insert_query);
3520    }
3521
3522    #[test]
3523    pub fn test_update_query(){
3524        let update_query = QueryBuilder::update().unwrap().table("blogs").set("title", ValueType::String("Hello Rust!".to_string())).set("author", ValueType::String("Necdet".to_string())).finish();
3525
3526        assert_eq!("UPDATE blogs SET title = 'Hello Rust!', author = 'Necdet';", update_query);
3527    }
3528
3529    #[test]
3530    pub fn test_delete_query(){
3531        let delete_query = QueryBuilder::delete().unwrap().table("blogs").where_("id", "=", ValueType::String("1".to_string())).finish();
3532
3533        assert_eq!("DELETE FROM blogs WHERE id = '1';", delete_query);
3534    }
3535
3536    #[test]
3537    pub fn test_select_query_declarative(){
3538        let mut select = QueryBuilder::select(["id", "title", "description", "point"].to_vec()).unwrap();
3539
3540        let select_query = select.table("blogs")
3541                                    .where_("id", "=", ValueType::Int32(10))
3542                                    .and("point", ">", ValueType::Int8(90))
3543                                    .or("id", "=", ValueType::Int64(20))
3544                                    .finish();
3545
3546        assert_eq!("SELECT id, title, description, point FROM blogs WHERE id = 10 AND point > 90 OR id = 20;", select_query)
3547    }
3548
3549    #[test]
3550    pub fn test_select_query_imperative(){
3551        let mut select = QueryBuilder::select(["*"].to_vec()).unwrap();
3552
3553        let select_query = select.table("blogs");
3554        select_query.where_("id", "=", ValueType::Uint8(5));
3555        select_query.or("id", "=", ValueType::Usize(25));
3556
3557        let finish_the_select_query = select_query.finish();
3558
3559        assert_eq!("SELECT * FROM blogs WHERE id = 5 OR id = 25;", finish_the_select_query);
3560    }
3561
3562    #[test]
3563    pub fn test_create_table() {
3564        let mut table_builder_2 = TableBuilder::create("blabla", "projects");
3565        let table_builder_2 = table_builder_2.if_not_exists();
3566    
3567        table_builder_2.add_column("id").col_type("INT").primary_key().auto_increment();
3568        table_builder_2.add_column("name").col_type("VARCHAR(40)").not_null();
3569        table_builder_2.add_column("owner_id").col_type("INT").not_null();
3570        
3571        // if we create a table, the first ForeignKeyItem's table field is not necessary.
3572        let opts = ForeignKey {
3573            first: ForeignKeyItem { table: "".to_string(), column: "owner_id".to_string() },
3574            second: ForeignKeyItem { table: "users".to_string(), column: "id".to_string() },
3575            constraint: None,
3576            on_delete: Some(ForeignKeyActions::Cascade),
3577            on_update: None
3578        };
3579        
3580        table_builder_2.foreign_key(opts);
3581    
3582        let table_builder_2 = table_builder_2.finish();
3583
3584        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();
3585
3586        assert_eq!(raw_query, table_builder_2);
3587    }
3588
3589    #[test]
3590    pub fn test_time_value_type(){
3591        let columns = ["name", "password", "last_login"].to_vec();
3592        let values = [ValueType::String("necoo33".to_string()), ValueType::String("123456".to_string()), ValueType::Datetime("CURRENT_TIMESTAMP".to_string())].to_vec();
3593    
3594        let time_insert_test = QueryBuilder::insert(columns, values).unwrap().table("users").finish();
3595
3596        assert_eq!(time_insert_test, "INSERT INTO users (name, password, last_login) VALUES ('necoo33', '123456', CURRENT_TIMESTAMP);");
3597
3598        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();
3599
3600        assert_eq!(time_update_test, "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE name = 'necoo33';")
3601    }
3602
3603    #[test]
3604    pub fn test_unix_epoch_times(){
3605        let columns = ["name", "password", "last_login"].to_vec();
3606        let values = [ValueType::String("necoo33".to_string()), ValueType::String("123456".to_string()), ValueType::EpochTime(134523452)].to_vec();
3607    
3608        let time_insert_with_unix_epoch_times_test = QueryBuilder::insert(columns, values).unwrap().table("users").finish();
3609        assert_eq!(time_insert_with_unix_epoch_times_test, "INSERT INTO users (name, password, last_login) VALUES ('necoo33', '123456', FROM_UNIXTIME(134523452));");
3610    
3611        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();
3612
3613        assert_eq!(time_update_with_unix_epoch_times_test, "UPDATE users SET last_login = FROM_UNIXTIME(3456436) WHERE name = 'necoo33';");
3614
3615        let columns = ["name", "password", "last_login", "created_at"].to_vec();
3616
3617        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();
3618
3619        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;")
3620    }
3621
3622    #[test]
3623    pub fn test_where_ins(){
3624        let columns = ["name", "age", "id", "last_login"].to_vec();
3625
3626        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3627
3628        let test_where_in = QueryBuilder::select(columns).unwrap().table("users").where_in("id", &ids).finish();
3629
3630        assert_eq!(test_where_in, "SELECT name, age, id, last_login FROM users WHERE id IN (1, 12, 8);");
3631
3632        let columns = ["name", "age", "id", "last_login"].to_vec();
3633
3634        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int32(8)].to_vec();
3635
3636        let test_where_not_in = QueryBuilder::select(columns).unwrap().table("users").where_not_in("id", &ids).finish();
3637
3638        assert_eq!(test_where_not_in, "SELECT name, age, id, last_login FROM users WHERE id NOT IN (1, 12, 8);");
3639
3640        let columns = ["name", "age", "id", "last_login"].to_vec();
3641
3642        let test_where_in_custom = QueryBuilder::select(columns).unwrap().table("users").where_in_custom("id", "1, 12, 8").finish();
3643
3644        assert_eq!(test_where_in_custom, "SELECT name, age, id, last_login FROM users WHERE id IN (1, 12, 8);");
3645
3646        let columns = ["name", "age", "id", "last_login"].to_vec();
3647
3648        let test_where_not_in_custom = QueryBuilder::select(columns).unwrap().table("users").where_not_in_custom("id", "1, 12, 8").finish();
3649
3650        assert_eq!(test_where_not_in_custom, "SELECT name, age, id, last_login FROM users WHERE id NOT IN (1, 12, 8);");
3651
3652        // test AND IN's
3653
3654        let columns = ["name", "id", "last_login"].to_vec();
3655
3656        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3657
3658        let test_and_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).and_in("id", &ids).finish();
3659
3660        assert_eq!(test_and_in, "SELECT name, id, last_login FROM users WHERE age > 35 AND id IN (1, 12, 8);");
3661
3662        let columns = ["name", "id", "last_login"].to_vec();
3663
3664        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3665
3666        let test_and_not_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).and_not_in("id", &ids).finish();
3667
3668        assert_eq!(test_and_not_in, "SELECT name, id, last_login FROM users WHERE age > 35 AND id NOT IN (1, 12, 8);");
3669
3670        // test OR IN's
3671
3672        let columns = ["name", "id", "last_login"].to_vec();
3673
3674        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3675
3676        let test_or_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).or_in("id", &ids).finish();
3677
3678        assert_eq!(test_or_in, "SELECT name, id, last_login FROM users WHERE age > 35 OR id IN (1, 12, 8);");
3679
3680        let columns = ["name", "id", "last_login"].to_vec();
3681
3682        let ids = [ValueType::Int32(1), ValueType::Int16(12), ValueType::Int64(8)].to_vec();
3683
3684        let test_or_not_in = QueryBuilder::select(columns).unwrap().table("users").where_("age", ">", ValueType::Int32(35)).or_not_in("id", &ids).finish();
3685
3686        assert_eq!(test_or_not_in, "SELECT name, id, last_login FROM users WHERE age > 35 OR id NOT IN (1, 12, 8);")
3687    }
3688
3689    #[test]
3690    pub fn test_count() {
3691        let count_of_users = QueryBuilder::count("*", None).table("users").where_("age", ">", ValueType::Int32(25)).finish();
3692
3693        assert_eq!(count_of_users, "SELECT COUNT(*) FROM users WHERE age > 25;".to_string());
3694
3695        let count_of_users_as_length = QueryBuilder::count("*", Some("length")).table("users").finish();
3696
3697        assert_eq!(count_of_users_as_length, "SELECT COUNT(*) AS length FROM users;".to_string());
3698    }
3699
3700    #[test]
3701    pub fn test_json_extract(){
3702        // tests with "select()" constructor
3703
3704        let select_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").finish();
3705
3706        assert_eq!(select_query_1, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students;".to_string());
3707        
3708        let select_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().json_extract("data", ".age", Some("student_age")).table("students").where_("successfull", "=", ValueType::Int8(1)).finish();
3709
3710        assert_eq!(select_query_2, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students WHERE successfull = 1;".to_string());
3711        
3712        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();
3713
3714        assert_eq!(select_query_3, "SELECT JSON_EXTRACT(data, '$.age') AS student_age FROM students WHERE JSON_EXTRACT(points, '$.name') > 85;".to_string());
3715
3716        // tests with ".where_cond()" method
3717
3718        let with_where = QueryBuilder::delete().unwrap().table("users").where_("id", ">", ValueType::Int32(200)).json_extract("id", ".user_id", None).finish();
3719
3720        assert_eq!(with_where, "DELETE FROM users WHERE JSON_EXTRACT(id, '$.user_id') > 200;".to_string());
3721
3722        // tests with ".table()" method
3723        
3724        let fields = ["name", "age"].to_vec();
3725        
3726        let with_table = QueryBuilder::select(fields).unwrap().table("users").json_extract("id", ".user_id", None).finish();
3727
3728        assert_eq!(with_table, "SELECT JSON_EXTRACT(id, '$.user_id') FROM users;".to_string());
3729
3730        // tests with ".and()" method
3731
3732        let fields = ["name", "age"].to_vec();
3733
3734        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();
3735
3736        assert_eq!(with_and_1, "SELECT name, age FROM height WHERE weight > 60 AND JSON_EXTRACT(height, '$.student_height') > 1.7;".to_string());
3737    
3738        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();
3739
3740        assert_eq!(with_and_2, "SELECT * FROM students WHERE weight > 60 AND JSON_EXTRACT(height, '$.student_height') > 1.7;".to_string());
3741
3742        // tests with ".or()" method
3743
3744        let fields = ["name", "age"].to_vec();
3745
3746        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();
3747
3748        assert_eq!(with_or_1, "SELECT name, age FROM height WHERE weight > 60 OR JSON_EXTRACT(height, '$.student_height') > 1.71;".to_string());
3749    
3750        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();
3751
3752        assert_eq!(with_or_2, "SELECT * FROM students WHERE weight > 60 OR JSON_EXTRACT(height, '$.student_height') > 1.71;".to_string());
3753
3754        // tests with "count()" constructor
3755
3756        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();
3757
3758        assert_eq!(count_query_1, "SELECT JSON_EXTRACT(age, '$.student_age') AS value, COUNT(*) FROM students GROUP BY points HAVING points > 75;".to_string());
3759
3760        // tests with ".order_by()" method
3761        
3762        let fields = ["title", "desc", "created_at", "updated_at", "keywords", "pics", "likes"].to_vec();
3763
3764        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();
3765
3766        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());
3767    
3768        // tests with ".json_extract()" method
3769
3770        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();
3771
3772        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());
3773    }
3774
3775    #[test]
3776    pub fn test_json_contains(){
3777        // test with "select()" constructor:
3778
3779        let ins = [ValueType::Int32(1), ValueType::Int32(5), ValueType::Int64(11)].to_vec();
3780        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();
3781
3782        assert_eq!(select_query, "SELECT JSON_CONTAINS(pic, '\"/files/hello.jpg\"', '$.path') FROM users WHERE id IN (1, 5, 11);".to_string());
3783
3784        // test with ".where_cond()" method:
3785
3786        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();
3787
3788        assert_eq!(where_query, "SELECT * FROM users WHERE JSON_CONTAINS(pic, '\"blablabla.jpg\"', '$.name');".to_string());
3789
3790        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();
3791
3792        assert_eq!(and_query_1, "SELECT * FROM users WHERE age > 15 AND JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3793
3794        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();
3795
3796        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());
3797        
3798        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();
3799    
3800        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());
3801
3802        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();
3803    
3804        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());
3805
3806        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();
3807    
3808        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());
3809        
3810        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();
3811
3812        assert_eq!(or_query_1, "SELECT * FROM users WHERE age > 15 OR JSON_CONTAINS(graduation_stats, 80.11, '$.average_point');".to_string());
3813        
3814        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();
3815        
3816        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());
3817                
3818        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();
3819            
3820        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());
3821        
3822        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();
3823            
3824        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());
3825        
3826        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();
3827            
3828        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());
3829
3830        let name = ValueType::JsonString("necdet".to_string());
3831        let id = ValueType::Int32(1);
3832        let is_active = ValueType::Boolean(true);
3833
3834        let object = vec![("name", &name), ("id", &id), ("isActive", &is_active)];
3835
3836        let mysql_json_object = JsonValue::MysqlJsonObject(&object);
3837
3838        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();
3839
3840        assert_eq!("SELECT * FROM users WHERE JSON_CONTAINS(pic, JSON_OBJECT('name', \"necdet\", 'id', 1, 'isActive', true), '$');", where_query_2)
3841    }
3842
3843    #[test]
3844    pub fn test_like_later_than_where_keywords(){
3845        let mut like_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap();
3846
3847        let like_query_1 = like_query_1.table("blogs")
3848                                                      .where_("id", "=", ValueType::Int32(5))
3849                                                      .like(["title", "description"].to_vec(), "hello")
3850                                                      .finish();
3851
3852        assert_eq!(like_query_1, "SELECT * FROM blogs WHERE id = 5 AND (title LIKE '%hello%' OR description LIKE '%hello%');");
3853    
3854        let mut like_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap();
3855
3856        let ins = vec![ValueType::Int32(1), ValueType::Int32(2), ValueType::Int32(3)];
3857        let like_query_2 = like_query_2.table("blogs")
3858                                                          .where_in("id", &ins)
3859                                                          .like(["title", "description", "keywords"].to_vec(), "necdet")
3860                                                          .limit(10)
3861                                                          .offset(0)
3862                                                          .finish();
3863
3864        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;")
3865    }
3866
3867    #[test]
3868    pub fn test_ordering_functions(){
3869        let order_by_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by("id", "asc").order_by("weight", "desc").order_by("point", "asc").finish();
3870
3871        assert_eq!(order_by_query, "SELECT * FROM users ORDER BY id ASC, weight DESC, point ASC;");
3872
3873        let order_by_random_query = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_random().finish();
3874
3875        assert_eq!(order_by_random_query, "SELECT * FROM users ORDER BY RAND();");
3876
3877        let roles = ["admin", "moderator", "member", "guest"].to_vec();
3878        let field_query_1 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles.clone()).finish();
3879
3880        assert_eq!(field_query_1, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest');");
3881
3882        let field_query_2 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by("id", "asc").order_by_field("role", roles.clone()).finish();
3883
3884        assert_eq!(field_query_2, "SELECT * FROM users ORDER BY id ASC, FIELD(role, 'admin', 'moderator', 'member', 'guest');");
3885
3886        let field_query_3 = QueryBuilder::select(["*"].to_vec()).unwrap().table("users").order_by_field("role", roles.clone()).order_by("id", "asc").finish();
3887
3888        assert_eq!(field_query_3, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest'), id ASC;");
3889        
3890        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();
3891
3892        assert_eq!(field_query_4, "SELECT * FROM users ORDER BY FIELD(role, 'admin', 'moderator', 'member', 'guest'), FIELD(status, 'active', 'banned', 'unverified');");
3893    }
3894
3895    #[test]
3896    pub fn test_unions(){
3897        let mut union_1 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap();
3898        union_1.table("users").where_("age", ">", ValueType::Int32(7));
3899
3900        let union_2 = QueryBuilder::select(vec!["name", "age", "id"]).unwrap()
3901                                                          .table("users")
3902                                                          .where_("age", "<", ValueType::Int32(15))
3903                                                          .union(vec![union_1])
3904                                                          .finish();
3905
3906        assert_eq!(union_2, "(SELECT name, age, id FROM users WHERE age < 15) UNION (SELECT name, age, id FROM users WHERE age > 7);");
3907
3908        let mut union_1 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
3909        union_1.table("blogs").like(vec!["title"], "text");
3910
3911        let mut union_2 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap();
3912        union_2.table("blogs").like(vec!["description"], "some text");
3913
3914        let union_3 = QueryBuilder::select(vec!["id", "title", "description", "published"]).unwrap()
3915                                                              .table("blogs")
3916                                                              .where_("published", "=", ValueType::Boolean(true))
3917                                                              .union_all(vec![union_1, union_2])
3918                                                              .finish();
3919
3920        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%');");
3921    }
3922
3923    #[test]
3924    pub fn test_json_value(){
3925        let name = ValueType::JsonString("necdet".to_string());
3926        let age = ValueType::Int8(25);
3927        let id = ValueType::Int32(1);
3928
3929        let values = vec![("name", &name), ("age", &age), ("id", &id)];
3930
3931        let json_object = JsonValue::Object(&values);
3932
3933        assert_eq!("{\"name\": \"necdet\", \"age\": 25, \"id\": 1}", json_object.to_string());
3934
3935        let mysql_json_object = JsonValue::MysqlJsonObject(&values);
3936
3937        assert_eq!("JSON_OBJECT('name', \"necdet\", 'age', 25, 'id', 1)", mysql_json_object.to_string());
3938
3939        let name2 = ValueType::JsonString("cevdet".to_string());
3940        let age2 = ValueType::Int8(24);
3941        let id2 = ValueType::Int32(2);
3942
3943        let name3 = ValueType::JsonString("serap".to_string());
3944        let age3 = ValueType::Int8(21);
3945        let id3 = ValueType::Int32(3);
3946
3947        let object1 = vec![("name", &name), ("age", &age), ("id", &id)];
3948        let object2 = vec![("name", &name2), ("age", &age2), ("id", &id2)];
3949        let object3 = vec![("name", &name3), ("age", &age3), ("id", &id3)];
3950
3951        let objects = vec![object1, object2, object3];
3952        
3953        let json_array = JsonValue::ObjectArray(&objects);
3954
3955        assert_eq!("[{\"name\": \"necdet\", \"age\": 25, \"id\": 1}, {\"name\": \"cevdet\", \"age\": 24, \"id\": 2}, {\"name\": \"serap\", \"age\": 21, \"id\": 3}]", json_array.to_string());
3956    }
3957
3958    #[test]
3959    pub fn test_json_array_append(){
3960        let lesson = ("lesson", &ValueType::String("math".to_string()));
3961        let point = ("point", &ValueType::Int32(100));
3962
3963        let values = vec![lesson, point];
3964        
3965        let object = JsonValue::MysqlJsonObject(&values);
3966
3967        let query = QueryBuilder::update().unwrap()
3968                                         .table("users")
3969                                         .json_array_append("points", Some(""), object.clone())
3970                                         .where_("id", "=", ValueType::Int8(1))
3971                                         .finish();
3972
3973        assert_eq!("UPDATE users SET points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3974
3975        let query = QueryBuilder::update().unwrap()
3976                                         .table("users")
3977                                         .set("status", ValueType::String("passed".to_string()))
3978                                         .json_array_append("points", Some(""), object)
3979                                         .where_("id", "=", ValueType::Int8(1))
3980                                         .finish();
3981
3982        assert_eq!("UPDATE users SET status = 'passed', points = JSON_ARRAY_APPEND(points, '$', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
3983    }
3984
3985    #[test]
3986    pub fn test_json_remove() {
3987        let query = QueryBuilder::update().unwrap()
3988                                         .table("blogs")
3989                                         .json_remove("likes", vec!["[10]"])
3990                                         .where_("blog_id", "=", ValueType::Int32(20))
3991                                         .finish();
3992
3993        assert_eq!(query, "UPDATE blogs SET likes = JSON_REMOVE(likes, '$[10]') WHERE blog_id = 20;");
3994        
3995        let query = QueryBuilder::update().unwrap()
3996                                         .table("blogs")
3997                                         .set("blabla", ValueType::Int32(50))
3998                                         .json_remove("likes", vec!["[10]", "[11]", "[12]"])
3999                                         .where_("blog_id", "=", ValueType::Int32(20))
4000                                         .finish();
4001
4002        println!("{}", query)
4003    }
4004
4005    #[test]
4006    pub fn test_json_set_and_json_replace(){
4007        let lesson = ("lesson", &ValueType::String("math".to_string()));
4008        let point = ("point", &ValueType::Int32(100));
4009
4010        let values = vec![lesson, point];
4011        
4012        let object = JsonValue::MysqlJsonObject(&values);
4013
4014        let query = QueryBuilder::update().unwrap()
4015                                                        .table("users")
4016                                                        .json_set("points", "[0]", object)
4017                                                        .where_("id", "=", ValueType::Int32(1))
4018                                                        .finish();
4019
4020        assert_eq!("UPDATE users SET points = JSON_SET(points, '$[0]', JSON_OBJECT('lesson', 'math', 'point', 100)) WHERE id = 1;", query);
4021
4022        let value = ValueType::Int32(100);
4023        let value = JsonValue::Initial(&value);
4024
4025        let query = QueryBuilder::update().unwrap()
4026                                         .table("users")
4027                                         .json_replace("points", "[0].point", value)
4028                                         .where_("id", "=", ValueType::Int32(1))
4029                                         .finish();
4030
4031        assert_eq!("UPDATE users SET points = JSON_REPLACE(points, '$[0].point', 100) WHERE id = 1;", query)
4032    }
4033
4034    #[test]
4035    pub fn test_json_value_initial_bugfix(){
4036        let file_name_val = ValueType::JsonString("chemistry".to_string());
4037        let file_name_val = JsonValue::Initial(&file_name_val);
4038
4039        let query = QueryBuilder::select(vec!["lesson_points"]).unwrap()
4040                                         .json_extract("points", &format!("[{}]", 2), Some("point"))
4041                                         .table("students")
4042                                         .where_("id", "=", ValueType::Int32(5))
4043                                         .and("adsf", "=", ValueType::Null)
4044                                         .json_contains("points", file_name_val, Some(&format!("[{}].name", 0)))
4045                                         .finish();
4046
4047        assert_eq!("SELECT JSON_EXTRACT(points, '$[2]') AS point FROM students WHERE id = 5 AND JSON_CONTAINS(points, '\"chemistry\"', '$[0].name');", query);
4048    }
4049
4050    #[test]
4051    pub fn test_timezones(){
4052        let query = QueryBuilder::select(vec!["*"]).unwrap().table("users").time_zone(Timezone::Istanbul).finish();
4053
4054        assert_eq!(query, "SET time_zone = Europe/Istanbul; SELECT * FROM users;");
4055        
4056        let query = QueryBuilder::select(vec!["*"]).unwrap()
4057                                         .table("users")
4058                                         .global_time_zone(Timezone::Amsterdam)
4059                                         .where_("id", "=", ValueType::Int32(3))
4060                                         .and("surname", "=", ValueType::String("Doe".to_string()))
4061                                         .finish();
4062
4063        assert_eq!(query, "SET GLOBAL time_zone = Europe/Amsterdam; SELECT * FROM users WHERE id = 3 AND surname = 'Doe';");
4064
4065        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();
4066
4067        assert_eq!(query, "SET time_zone = America/New_York; UPDATE users SET age = 26, last_online_date = CURRENT_TIMESTAMP WHERE id = 234;");
4068
4069        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();
4070
4071        assert_eq!(query, "SET GLOBAL time_zone = America/New_York; UPDATE users SET age = 26, last_online_date = CURRENT_TIMESTAMP WHERE id = 234;");
4072    }
4073
4074    #[test]
4075    pub fn test_joins(){
4076        let query = QueryBuilder::select(vec!["*"]).unwrap()
4077                                         .table("students s")
4078                                         .inner_join("grades g", "s.id", "=", "g.student_id")
4079                                         .where_("id", "=", ValueType::Int32(10))
4080                                         .finish();
4081
4082        assert_eq!(query, "SELECT * FROM students s INNER JOIN grades g ON s.id = g.student_id WHERE id = 10;");
4083
4084        let query = QueryBuilder::select(vec!["*"]).unwrap()
4085                                         .table("students s")
4086                                         .left_join("grades g", "s.id", "=", "g.student_id")
4087                                         .where_("id", "=", ValueType::Int32(10))
4088                                         .finish();
4089
4090        assert_eq!(query, "SELECT * FROM students s LEFT JOIN grades g ON s.id = g.student_id WHERE id = 10;");
4091    }
4092}