1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::ast::*;
/// A builder for an `UPDATE` statement.
#[derive(Debug, PartialEq, Clone)]
pub struct Update<'a> {
pub(crate) table: Table<'a>,
pub(crate) columns: Vec<Column<'a>>,
pub(crate) values: Vec<DatabaseValue<'a>>,
pub(crate) conditions: Option<ConditionTree<'a>>,
}
impl<'a> From<Update<'a>> for Query<'a> {
#[inline]
fn from(update: Update<'a>) -> Self {
Query::Update(Box::new(update))
}
}
impl<'a> Update<'a> {
/// Creates the basis for an `UPDATE` statement to the given table.
#[inline]
pub fn table<T>(table: T) -> Self
where
T: Into<Table<'a>>,
{
Self {
table: table.into(),
columns: Vec::new(),
values: Vec::new(),
conditions: None,
}
}
/// Add another column value assignment to the query
///
/// ```rust
/// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
/// let query = Update::table("users").set("foo", 10).set("bar", false);
/// let (sql, params) = Sqlite::build(query);
///
/// assert_eq!("UPDATE `users` SET `foo` = ?, `bar` = ?", sql);
///
/// assert_eq!(
/// vec![
/// ParameterizedValue::Integer(10),
/// ParameterizedValue::Boolean(false),
/// ],
/// params,
/// );
/// ```
pub fn set<K, V>(mut self, column: K, value: V) -> Update<'a>
where
K: Into<Column<'a>>,
V: Into<DatabaseValue<'a>>,
{
self.columns.push(column.into());
self.values.push(value.into());
self
}
/// Adds `WHERE` conditions to the query. See
/// [Comparable](trait.Comparable.html#required-methods) for more examples.
///
/// ```rust
/// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
/// let query = Update::table("users").set("foo", 1).so_that("bar".equals(false));
/// let (sql, params) = Sqlite::build(query);
///
/// assert_eq!("UPDATE `users` SET `foo` = ? WHERE `bar` = ?", sql);
///
/// assert_eq!(
/// vec![
/// ParameterizedValue::Integer(1),
/// ParameterizedValue::Boolean(false),
/// ],
/// params,
/// );
/// ```
///
/// We can also use a nested `SELECT` in the conditions.
///
/// ```rust
/// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
/// let select = Select::from_table("bars").column("id").so_that("uniq_val".equals(3));
/// let query = Update::table("users").set("foo", 1).so_that("bar".equals(select));
/// let (sql, params) = Sqlite::build(query);
///
/// assert_eq!(
/// "UPDATE `users` SET `foo` = ? WHERE `bar` = (SELECT `id` FROM `bars` WHERE `uniq_val` = ?)",
/// sql
/// );
///
/// assert_eq!(
/// vec![
/// ParameterizedValue::Integer(1),
/// ParameterizedValue::Integer(3),
/// ],
/// params,
/// );
/// ```
pub fn so_that<T>(mut self, conditions: T) -> Self
where
T: Into<ConditionTree<'a>>,
{
self.conditions = Some(conditions.into());
self
}
}