query_builder/
lib.rs

1//! # About
2//! This crate is intended to be easy to use for creating
3//! SQL-Queries dynamically as you need it.
4//!
5//! # Usage
6//! For creating a simple SELECT-Query you first need to add
7//! `query_builder = "*"` to your `Cargo.toml` file (you may of cource replace * with any version)<br>
8//! In your code write `extern crate query_builder` and `use query_builder::*` to
9//! import all structs and enums. <br>
10//! Finally creating the [`SelectQuery`] looks like this:
11//! 
12//! ```
13//! use query_builder::SelectQuery;
14//!
15//! let query = SelectQuery::select(&["*"]).from("users");
16//! // make sure the query looks like expected
17//! assert_eq!(query.as_string(), "SELECT * FROM users");
18//! ```
19//! <br>
20//! Creating a [`InsertQuery`] works similar:
21//! 
22//! ```
23//! use query_builder::{InsertQuery, Value};
24//!
25//! // create the basic query
26//! let mut query = InsertQuery::into("users");
27//! // add values to the query
28//! query.values.insert("name", Value::Varchar("george"));
29//!
30//! // make sure that the query looks like expected
31//! assert_eq!(query.as_string(), "INSERT INTO users(name) VALUES('george')");
32//! ```
33//! <br>
34//! More detailed explanations and examples can be found at the corresponding sections
35//! to the structs and enums
36//!
37//! [`SelectQuery`]: ./struct.SelectQuery.html
38//! [`InsertQuery`]: ./struct.InsertQuery.html
39//! [`Value`]: ./enum.Value.html
40
41
42// std imports
43use std::collections::BTreeMap;
44use std::fmt::{Display, Formatter, Result as FormatResult};
45#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
46/// Enum representing common SQL-datatypes
47pub enum Value<'c> {
48    Varchar(&'c str),
49    Bool(bool),
50    Tinyint(i8),
51    UnsignedTinyint(u8),
52    Smallint(i16),
53    UnsignedSmallint(u16),
54    Int(i32),
55    UnsignedInt(u32),
56    Bigint(i64),
57    UnsignedBigint(u64),
58}
59
60#[allow(unused_assignments)]
61impl<'c> Value<'c> {
62    /// Convert the Value to a [`String`]
63    /// 
64    /// ## Example
65    /// 
66    /// ```
67    /// use query_builder::Value;
68    /// 
69    /// // Put single quotes around the varchar to not conflict with e.g. MySQL when inserting data
70    /// let v = Value::Varchar("steven");
71    /// assert_eq!(v.as_string(), "'steven'");
72    ///
73    /// // Bools are written in caps to make them stand out in queries
74    /// let v = Value::Bool(true);
75    /// assert_eq!(v.as_string(), "TRUE");
76    ///
77    /// // applies to all numeric Values
78    /// let v = Value::Int(42);
79    /// assert_eq!(v.as_string(), "42");
80    /// ```
81    /// 
82    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
83    /// 
84    pub fn as_string(&self) -> String {
85        match *self {
86            Value::Varchar(v) => format!("'{}'", v),
87            Value::Bool(b) => if b {
88                "TRUE".to_string()
89            } else {
90                "FALSE".to_string()
91            },
92            Value::Tinyint(t) => format!("{}", t),
93            Value::UnsignedTinyint(ut) => format!("{}", ut),
94            Value::Smallint(s) => format!("{}", s),
95            Value::UnsignedSmallint(us) => format!("{}", us),
96            Value::Int(i) => format!("{}", i),
97            Value::UnsignedInt(ui) => format!("{}", ui),
98            Value::Bigint(bi) => format!("{}", bi),
99            Value::UnsignedBigint(ubi) => format!("{}", ubi),
100        }
101    }
102}
103
104impl<'c> Display for Value<'c> {
105    fn fmt(&self, f: &mut Formatter) -> FormatResult {
106        write!(f, "{}", self.as_string())
107    }
108}
109
110#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
111/// Enum representing the ways to combine conditional parts of a query
112pub enum Condition {
113    And,
114    Or
115}
116
117impl Display for  Condition {
118    fn fmt(&self, f: &mut Formatter) -> FormatResult {
119        match *self {
120            Condition::And  => write!(f, "AND"),
121            Condition::Or   => write!(f, "OR"),
122        }
123    }
124}
125
126#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
127/// Representing the way to format the ORDER BY clause of some queries
128pub enum OrderBy<'b> {
129    Row(&'b str),
130    Expression(&'b str),
131}
132
133impl<'b> OrderBy<'b> {
134    /// Display the [`OrderBy`] clause as a [`String`]
135    /// Currently it doesen't matter if you used [`OrderBy::Row`] or
136    /// [`OrderBy::Expression`] as both result in the exat same [`String`] though
137    /// this might change in the future
138    /// 
139    /// [`OrderBy`]: ./enum.OrderBy.html
140    /// [`String`]: https://www.doc.rust-lang.org/std/string/struct.String.html
141    /// [`OrderBy::Row`]: ./enum.OrderBy.html#variant.Row
142    /// [`OrderBy::Expression`]: ./enum.OrderBy.html#variant.Expression
143    pub fn as_string(&self) -> String {
144        match *self {
145            OrderBy::Row(r) => format!("ORDER BY {}", r),
146            OrderBy::Expression(e)  => format!("ORDER BY {}", e),
147        }
148    }
149}
150
151impl<'b> Display for OrderBy<'b> {
152    fn fmt(&self, f: &mut Formatter) -> FormatResult {
153        write!(f, "{}", self.as_string())
154    }
155}
156
157#[derive(Debug)]
158/// Struct representing an WHERE-Clause
159/// 
160/// 
161pub struct WhereClause<'a, 'b> {
162    tbl: &'a str,
163    cond: Value<'b>,
164    how: Condition,
165}
166
167impl<'a, 'b> WhereClause<'a, 'b> {
168    /// Creates a new WHERE-clause
169    /// 
170    /// If the Value of `how` is none when initializing the clause, [`Condition::And`]
171    /// is assumed and used for the clause.
172    /// 
173    /// 
174    /// 
175    /// *Note:* If the [`WhereClause`] is the first one to be inserted in the string of an query, 
176    /// the condition will be left out.
177    /// 
178    /// [`WhereClause`]: ./struct.WhereClause.html
179    /// [`Condition::And`]: ./enum.Condition.html#variant.And
180    ///  
181    pub fn new(table: &'a str, cond: Value<'b>, how: Option<Condition>) -> WhereClause<'a, 'b> {
182        if let Some(c) = how {
183            WhereClause {
184                tbl: table,
185                cond: cond,
186                how: c
187            }
188        } else {
189            WhereClause {
190                tbl: table,
191                cond: cond,
192                how: Condition::And,
193            }
194        }
195    }
196
197    /// Returns a [`String`] representing the [`WhereClause`] with it's condition part
198    /// The returned [`String`] is also the default representation returned when calling the 
199    /// [`Display`] trait functions on this struct.
200    /// 
201    /// ## Example
202    /// 
203    /// ```
204    /// use query_builder::{WhereClause, Condition, Value};
205    /// 
206    /// let wclause = WhereClause::new("user", Value::Varchar("gerald"), Some(Condition::Or));
207    /// 
208    /// assert_eq!(wclause.as_string(), "OR user = 'gerald'")
209    /// ```
210    /// 
211    /// [`WhereClause`]: ./struct.WhereClause.html
212    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
213    /// [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
214    pub fn as_string(&self) -> String {
215        format!("{} {} = {}", self.how, self.tbl, self.cond)
216    }
217
218    /// Returns a [`String`] representing the [`WhereClause`] without it's condition part
219    /// but with the `WHERE` phrase in the beginning
220    /// 
221    /// ## Example
222    /// 
223    /// ```
224    /// use query_builder::{WhereClause, Value};
225    /// 
226    /// let clause = WhereClause::new("user", Value::Varchar("thomas"), None);
227    /// 
228    /// assert_eq!(clause.as_string_no_cond_with_prefix(), "WHERE user = 'thomas'")
229    /// ```
230    /// 
231    /// [`WhereClause`]: ./struct.WhereClause.html
232    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
233    pub fn as_string_no_cond_with_prefix(&self) -> String {
234        format!("WHERE {} = {}", self.tbl, self.cond)
235    }
236
237    /// Returns a [`String`] representing the [`WhereClause`] without `WHERE` prefix and 
238    /// without it's conditional parts
239    /// 
240    /// ## Example
241    /// 
242    /// ```
243    /// use query_builder::{WhereClause, Value};
244    /// 
245    /// let clause = WhereClause::new("user", Value::Varchar("jeanny"), None);
246    /// 
247    /// assert_eq!(clause.as_string_no_cond(), "user = 'jeanny'")
248    /// ```
249    /// 
250    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
251    /// [`WhereClause`]: ./struct.WhereClause.html
252    pub fn as_string_no_cond(&self) -> String {
253        format!("{} = {}", self.tbl, self.cond)
254    }
255
256}
257
258impl<'a, 'b> Display for WhereClause<'a, 'b> {
259    fn fmt(&self, f: &mut Formatter) -> FormatResult {
260        write!(f, "{}", self.as_string())
261    }
262} 
263
264
265
266#[derive(Debug)]
267/// Struct representing a SQL-INSERT Query
268/// A simple query to select everything from a table can be created like this:
269/// 
270/// ## Example 
271/// 
272/// ```
273/// use query_builder::SelectQuery;
274///
275/// // create the query
276/// let query = SelectQuery::select(&["*"]).from("users");
277///
278/// // make sure it looks like you would expect it to look
279/// assert_eq!(query.as_string(), "SELECT * FROM users");
280/// ```
281pub struct SelectQuery<'a, 'c> {
282    select: Vec<&'a str>,
283    from: &'a str,
284    pub whre: Vec<WhereClause<'a, 'c>>,
285    limit: Option<usize>,
286    order_by: Option<OrderBy<'c>>
287}
288
289impl<'a, 'c> Display for SelectQuery<'a, 'c> {
290    fn fmt(&self, f: &mut Formatter) -> FormatResult {
291        write!(f, "{}", self.as_string())
292    }
293}
294
295
296#[allow(unused_assignments)]
297impl<'a, 'c> SelectQuery<'a, 'c> {
298    /// Creates a new [`SelectQuery`] that selects data from the row/s `rows`
299    ///
300    /// [`SelectQuery`]: ./struct.SelectQuery.html
301    pub fn select(rows: &[&'a str]) -> SelectQuery<'a, 'c> {
302        SelectQuery {
303            select: rows.to_vec(),
304            from: "",
305            whre: Vec::new(),
306            limit: None,
307            order_by: None,
308        }
309    }
310
311    /// Sets the table to select from to the value of `t`
312    /// ## Example
313    /// 
314    /// ```
315    /// use query_builder::SelectQuery;
316    ///
317    /// let q = SelectQuery::select(&["user"]).from("users");
318    ///
319    /// assert_eq!(q.as_string(), "SELECT user FROM users")
320    /// ```
321    pub fn from(mut self, t: &'a str) -> Self {
322        self.from = t;
323        self
324    }
325
326    /// Sets the limit value of the Query to the value of `l`
327    /// ## Example
328    /// 
329    /// ```
330    /// use query_builder::SelectQuery;
331    ///
332    /// let mut q = SelectQuery::select(&["user"]).from("users");
333    /// q.limit(12);
334    ///
335    /// assert_eq!(q.as_string(), "SELECT user FROM users LIMIT 12")
336    /// ```
337    pub fn limit(&mut self, l: usize) {
338        self.limit = Some(l);
339    }
340
341    /// Return whether or not the [`SelectQuery`] has a limit
342    /// ## Example
343    /// 
344    /// ```
345    /// use query_builder::SelectQuery;
346    ///
347    /// let mut q = SelectQuery::select(&["user"]).from("users");
348    /// q.limit(12);
349    /// 
350    /// assert!(q.has_limit());
351    /// 
352    /// q.clear_limit();
353    /// assert!(!q.has_limit());
354    /// ```
355    /// [`SelectQuery`]: ./struct.SelectQuery.html
356    pub fn has_limit(&self) -> bool {
357        if let Some(_) = self.limit {
358            return true;
359        }
360
361        false
362    }
363
364    /// Returns the value of the Limit of the [`SelectQuery`] if there is one
365    /// ## Example
366    /// 
367    /// ```
368    /// use query_builder::SelectQuery;
369    /// 
370    /// let mut q = SelectQuery::select(&["user"]).from("users");
371    /// assert_eq!(q.get_limit(), None);
372    /// 
373    /// q.limit(12);
374    /// assert_eq!(q.get_limit(), Some(12));
375    /// ```
376    /// [`SelectQuery`]: ./struct.SelectQuery.html
377    pub fn get_limit(&self) -> Option<usize> {
378        self.limit
379    }
380
381    /// Removes the limit from the query
382    /// ## Example
383    /// 
384    /// ```
385    /// use query_builder::SelectQuery;
386    ///
387    /// let mut q = SelectQuery::select(&["user"]).from("users");
388    /// 
389    /// // set the limit
390    /// q.limit(42);
391    /// assert_eq!(q.as_string(), "SELECT user FROM users LIMIT 42");
392    ///
393    /// // clear limit
394    /// q.clear_limit();
395    /// 
396    /// assert_eq!(q.as_string(), "SELECT user FROM users");
397    /// ```
398    pub fn clear_limit(&mut self) {
399        self.limit = None;
400    }
401
402    /// Adds a ORDER BY clause to the query
403    pub fn order_by(&mut self, ob: OrderBy<'c>) {
404        self.order_by = Some(ob);
405    }
406    /// Creates the string representation of the query
407    /// ## Example
408    /// 
409    /// ```
410    /// use query_builder::SelectQuery;
411    ///
412    /// let mut q = SelectQuery::select(&["*"]).from("users");
413    ///
414    /// assert_eq!(q.as_string(), "SELECT * FROM users")
415    /// ```
416    pub fn as_string(&self) -> String {
417        let mut res: String = String::new();
418        if !self.select.is_empty() {
419            res = format!("SELECT {}", self.select[0]);
420            if self.select.len() > 1 {
421                for s in self.select[1..].iter() {
422                    res = format!("{}, {}", res, s);
423                }
424            }
425        }
426
427        if self.from.len() > 1 {
428            res = format!("{} FROM {}", res, self.from);
429        }
430
431        if !self.whre.is_empty() {
432            let c = &self.whre[0];
433            res = format!("{} {}", res, c.as_string_no_cond_with_prefix());
434            for clause in &self.whre[1..] {
435                res = format!("{} {}", res, clause);
436            }
437        }
438
439        if let Some(l) = self.limit {
440            res = format!("{} LIMIT {}", res, l);
441        }
442
443        if let Some(ref ob) = self.order_by {
444            res = format!("{} {}", res, ob);
445        }
446
447        res
448    }
449}
450
451
452#[derive(Debug)]
453/// Struct representing an SQL Insert Statement
454/// 
455/// Creating a query that works requires at least to function calls.
456/// 
457/// ## Examples
458/// 
459/// ```
460/// use query_builder::{InsertQuery, Value};
461/// 
462/// // construct the InsertQuery to insert into table 'users'
463/// let mut q = InsertQuery::into("users");
464/// 
465/// // add the value 'jonathan' to be added into the row 'name'
466/// q.values.insert("name", Value::Varchar("jonathan"));
467/// 
468/// assert_eq!(q.as_string(), "INSERT INTO users(name) VALUES('jonathan')");
469/// ```
470/// 
471pub struct InsertQuery<'a> {
472    into: &'a str,
473    /// A map of the values to inserted into the table. 
474    /// The map is intended to be <row, value>
475    pub values: BTreeMap<&'a str, Value<'a>>,
476}
477
478impl<'a> Display for InsertQuery<'a> {
479    fn fmt(&self, f: &mut Formatter) -> FormatResult {
480        write!(f, "{}", self.as_string())
481    }
482}
483
484#[allow(unused_assignments)]
485impl<'a> InsertQuery<'a> {
486    /// Creates a new [`InsertQuery`] that puts data into `table`.
487    /// 
488    /// [`InsertQuery`]: ./struct.InsertQuery.html
489    pub fn into(table: &'a str) -> InsertQuery<'a> {
490        InsertQuery {
491            into: table,
492            values: BTreeMap::new(),
493        }
494    }
495
496    /// Returns a [`String`] that represents the [`InsertQuery`] in a valid SQL statement
497    /// ## Example
498    /// ```
499    /// use query_builder::{Value, InsertQuery};
500    ///
501    /// let mut q = InsertQuery::into("users");
502    /// q.values.insert("name", Value::Varchar("greg"));
503    ///
504    /// assert_eq!(q.as_string(), "INSERT INTO users(name) VALUES('greg')")
505    /// ```
506    /// 
507    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
508    /// [`InsertQuery`]: ./struct.InsertQuery.html
509    pub fn as_string(&self) -> String {
510        let mut res = String::new();
511        let (mut vals, mut vals_list) = (String::new(), String::new());
512
513        res = format!("INSERT INTO {}", self.into);
514
515        if !self.values.is_empty() {
516            let mut keys = self.values.keys();
517            let key = keys.next().unwrap();
518            vals = format!("{}", key);
519            vals_list = format!("{}", self.values[key]);
520
521            for k in keys {
522                vals = format!("{}, {}", vals, k);
523                vals_list = format!("{}, {}", vals_list, self.values[k]);
524            }
525        }
526
527        format!("{}({}) VALUES({})", res, vals, vals_list)
528    }
529}
530
531#[derive(Debug)]
532/// Struct representing a SQL Delete Statement
533pub struct DeleteQuery<'a, 'c> {
534    from: &'a str,
535    pub whre: Vec<WhereClause<'a, 'c>>,
536    limit: Option<usize>,
537    order_by: Option<OrderBy<'c>>,
538}
539
540impl<'a, 'c> Display for DeleteQuery<'a, 'c> {
541    fn fmt(&self, f: &mut Formatter) -> FormatResult {
542        write!(f, "{}", self.as_string())
543    }
544}
545
546#[allow(unused_assignments)]
547impl<'a, 'c> DeleteQuery<'a, 'c> {
548    /// Return a new [`DeleteQuery`] that deletes data from table `table`
549    /// 
550    /// [`DeleteQuery`]: ./struct.DeleteQuery.html
551    pub fn from(table: &'a str) -> DeleteQuery {
552        DeleteQuery {
553            from: table,
554            whre: Vec::new(),
555            limit: None,
556            order_by: None,
557        }
558    }
559
560    /// Sets the limit of items to delete
561    /// ## Example
562    /// 
563    /// ```
564    /// use query_builder::{DeleteQuery, Value, WhereClause};
565    /// 
566    /// let mut query = DeleteQuery::from("users");
567    /// // add values to delete
568    /// query.whre.push(WhereClause::new("name", Value::Varchar("gregory"), None));
569    /// 
570    /// // add the limit
571    /// query.limit(1);
572    /// 
573    /// // make sure the query looks like expected
574    /// assert_eq!(query.as_string(), "DELETE FROM users WHERE name = 'gregory' LIMIT 1");
575    /// ```
576    pub fn limit(&mut self, limit: usize) {
577        self.limit = Some(limit);
578    }
579
580    /// Returns the limit of the [`DeleteQuery`]
581    /// ## Example
582    /// 
583    /// ```
584    /// use query_builder::{DeleteQuery, Value};
585    /// 
586    /// // create query
587    /// let mut query = DeleteQuery::from("users");
588    /// 
589    /// // set the limit
590    /// query.limit(12);
591    /// 
592    /// assert_eq!(query.get_limit(), Some(12));
593    /// ```
594    /// 
595    /// [`DeleteQuery`]: ./struct.DeleteQuery.html
596    pub fn get_limit(&self) -> Option<usize> {
597        self.limit
598    }
599
600    /// Removes the limit from the [`DeleteQuery`]
601    /// 
602    /// ## Example
603    /// 
604    /// ```
605    /// use query_builder::DeleteQuery;
606    /// 
607    /// let mut query = DeleteQuery::from("users");
608    /// /* add limit to the query */
609    /// query.limit(12);
610    /// 
611    /// assert_eq!(query.get_limit(), Some(12));
612    /// 
613    /// /* clear the limit */
614    /// query.clear_limit();
615    /// 
616    /// assert_eq!(query.get_limit(), None);
617    /// 
618    /// ```
619    /// [`DeleteQuery`]: ./struct.DeleteQuery.html
620    pub fn clear_limit(&mut self) {
621        self.limit = None;
622    }
623
624    /// Adds a [`OrderBy`] clause to the query
625    /// 
626    /// ## Example
627    /// 
628    /// ```
629    /// use query_builder::{DeleteQuery, OrderBy};
630    /// 
631    /// let mut query = DeleteQuery::from("continents");
632    /// query.order_by(OrderBy::Row("population"));
633    /// 
634    /// assert_eq!(query.as_string(), "DELETE FROM continents ORDER BY population");
635    /// ```
636    /// [`OrderBy`]: ./enum.OrderBy.html
637    pub fn order_by(&mut self, ob: OrderBy<'c>) {
638        self.order_by = Some(ob);
639    }
640
641    /// Returns either `true` or `false` depending on whether
642    /// or not the [`DeleteQuery`] contains a [`OrderBy`] clause
643    /// 
644    /// ## Example
645    /// 
646    /// ```
647    /// use query_builder::{DeleteQuery, OrderBy};
648    /// 
649    /// let mut query = DeleteQuery::from("states");
650    /// query.order_by(OrderBy::Row("population"));
651    /// 
652    /// assert!(query.is_ordered());
653    /// ```
654    /// [`DeleteQuery`]: ./struct.DeleteQuery.html
655    /// [`OrderBy`]: ./enum.OrderBy.html
656    pub fn is_ordered(&self) -> bool {
657        if let Some(_) = self.order_by {
658            true
659        }
660        else {
661            false
662        }
663    }
664
665    /// Removes the ORDER BY clause from the query
666    pub fn clear_order_by(&mut self) {
667        self.order_by = None;
668    }
669
670    /// Return a [`String`] representing the [`DeleteQuery`]
671    /// 
672    /// ## Example
673    /// ```
674    /// use query_builder::{DeleteQuery, Value, WhereClause, Condition};
675    /// 
676    /// // create basic query
677    /// let mut query = DeleteQuery::from("people");
678    /// 
679    /// // set parameter of the query
680    /// query.whre.push(WhereClause::new("name", Value::Varchar("justine"), None));
681    /// query.whre.push(WhereClause::new("age", Value::Int(24), Some(Condition::And)));
682    /// query.limit(1);
683    /// 
684    /// assert_eq!(query.as_string(), "DELETE FROM people WHERE name = 'justine' AND age = 24 LIMIT 1");
685    /// ```
686    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
687    pub fn as_string(&self) -> String {
688        let mut res = String::new();
689
690        res = format!("DELETE FROM {}", self.from);
691
692        if !self.whre.is_empty() {
693            /* get the first element from the vector */
694            let c = &self.whre[0];
695            res = format!("{} {}", res, c.as_string_no_cond_with_prefix());
696            for clause in &self.whre[1..] {
697                res = format!("{} {}", res, clause);
698            }
699        }
700
701        if let Some(ref o) = self.order_by {
702            res = format!("{} {}", res, o);
703        }
704
705        if let Some(l) = self.limit {
706            res = format!("{} LIMIT {}", res, l);
707        }
708
709        res
710    }
711}
712
713#[derive(Debug)]
714/// Struct representing an SQL Update statement
715pub struct UpdateQuery<'a, 'c> {
716    update: &'a str,
717    /// A Map containing the field to set with the appropiate values to them
718    pub set: BTreeMap<&'a str, Value<'c>>,
719    /// All [`WhereClause`]s for conditional Updating in this 
720    /// [`UpdateQuery`]
721    /// 
722    /// [`WhereClause`]: ./struct.WhereClause.html
723    /// [`UpdateQuery`]: ./struct.UpdateQuery.html
724    pub whre: Vec<WhereClause<'a, 'c>>,
725    limit: Option<usize>,
726}
727
728impl<'a, 'c> Display for UpdateQuery<'a, 'c> {
729    fn fmt(&self, f: &mut Formatter) -> FormatResult {
730        write!(f, "{}", self.as_string())
731    }
732}
733
734#[allow(unused_assignments)]
735impl<'a, 'c> UpdateQuery<'a, 'c> {
736    /// Returns a new [`UpdateQuery`] that updates the table `table`
737    /// 
738    /// ## Example
739    /// 
740    /// ```
741    /// use query_builder::UpdateQuery;
742    /// 
743    /// let query = UpdateQuery::update("town");
744    /// 
745    /// assert_eq!(query.as_string(), "UPDATE town");
746    /// ```
747    /// 
748    /// [`UpdateQuery`]: ./struct.UpdateQuery.html
749    pub fn update(table: &'a str) -> UpdateQuery {
750        UpdateQuery {
751            update: table,
752            set: BTreeMap::new(),
753            whre: Vec::new(),
754            limit: None,
755        }
756    }
757
758    /// Set the limit of the Query to the value of `l`
759    /// ## Example
760    /// 
761    /// ```
762    /// use query_builder::{UpdateQuery, Value};
763    /// 
764    /// let mut query = UpdateQuery::update("users");
765    /// // set the limit
766    /// query.limit(12);
767    /// 
768    /// // assert that the limit is actually there
769    /// assert_eq!(query.get_limit(), Some(12))
770    /// ```
771    pub fn limit(&mut self, l: usize) {
772        self.limit = Some(l);
773    }
774
775    /// Returns whether or not the [`UpdateQuery`] has a limit
776    /// 
777    /// ## Example
778    /// 
779    /// ```
780    /// use query_builder::UpdateQuery;
781    ///  
782    /// // create the query
783    /// let mut query = UpdateQuery::update("cities");
784    /// 
785    /// assert_eq!(query.has_limit(), false);
786    /// 
787    /// // set limit
788    /// query.limit(1);
789    /// assert_eq!(query.has_limit(), true);
790    /// ```
791    /// [`UpdateQuery`]: ./struct.UpdateQuery.html
792    pub fn has_limit(&self) -> bool {
793        if let Some(_) = self.limit {
794            return true;
795        }
796
797        false
798    }
799    /// Returns the limit of the [`UpdateQuery`] if there is one
800    /// 
801    /// ## Example
802    /// 
803    /// ```
804    /// use query_builder::UpdateQuery;
805    /// // create the query
806    /// let mut query = UpdateQuery::update("countries");
807    /// 
808    /// assert_eq!(query.get_limit(), None);
809    /// 
810    /// // set the limit
811    /// query.limit(12);
812    /// assert_eq!(query.get_limit(), Some(12));
813    /// ```
814    /// [`UpdateQuery`]: ./struct.UpdateQuery.html
815    pub fn get_limit(&self) -> Option<usize> {
816        self.limit
817    }
818
819    /// Returns the [`String`] representation of the [`UpdateQuery`]
820    /// 
821    /// ## Example
822    /// 
823    /// ```
824    /// use query_builder::{UpdateQuery, Value};
825    /// 
826    /// let mut query = UpdateQuery::update("users");
827    /// 
828    /// query.set.insert("name", Value::Varchar("jeff")); 
829    /// query.limit(1);
830    /// 
831    /// assert_eq!(query.as_string(),"UPDATE users SET name = 'jeff' LIMIT 1");
832    /// ```
833    /// [`UpdateQuery`]: ./struct.UpateQuery.html
834    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
835    pub fn as_string(&self) -> String {
836        let mut res = String::new();
837
838        res = format!("UPDATE {}", self.update);
839
840        if !self.set.is_empty() {
841            let mut keys = self.set.keys();
842            let key = keys.next().unwrap();
843
844            res = format!("{} SET {} = {}", res, key, self.set[key]);
845
846            for k in keys {
847                res = format!("{}, {} = {}", res, k, self.set[k]);
848            }
849        }
850
851        if !self.whre.is_empty() {
852            let c = &self.whre[0];
853            res = format!("{} {}", res, c.as_string_no_cond_with_prefix());
854            for clause in &self.whre[1..] {
855                res = format!("{} {}", res, clause);
856            }
857        }
858
859        if let Some(l) = self.limit {
860            res = format!("{} LIMIT {}", res, l);
861        }
862
863        res
864    }
865}