qubl/
lib.rs

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