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}