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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::prelude::*;
use postgres_types::ToSql;
pub struct UpdateBuilder {
table: String,
fields: Vec<String>,
where_cols: Vec<String>,
params: Vec<Box<dyn ToSql + Sync>>,
}
impl UpdateBuilder {
pub fn new(from: &str) -> Self {
UpdateBuilder {
table: from.into(),
fields: vec![],
where_cols: vec![],
params: vec![],
}
}
}
impl QueryBuilder for UpdateBuilder {
fn get_query(&self) -> String {
let mut result = format!("UPDATE {}", self.table);
if self.fields.len() > 0 {
let fields_query = self.fields.join(", ");
result = format!("{} SET {}", result, fields_query);
}
if self.where_cols.len() > 0 {
let where_query = self.where_cols.join(" AND ");
result = format!("{} WHERE {}", result, where_query);
}
result
}
fn has_params(&self) -> bool {
self.params.len() > 0
}
fn next_index(&self) -> usize {
self.params.len() + 1
}
fn get_ref_params(self) -> Vec<&'static (dyn ToSql + Sync)> {
let mut args: Vec<&(dyn ToSql + Sync)> = vec![];
for item in self.params {
args.push(Box::leak(item));
}
args
}
}
impl QueryBuilderWithWhere for UpdateBuilder {
fn where_eq<T: 'static + ToSql + Sync + Clone>(&mut self, field: &str, value: T) {
self
.where_cols
.push(format!("{} = ${}", field, self.next_index()));
self.params.push(Box::new(value.clone()));
}
fn where_ne<T: 'static + ToSql + Sync + Clone>(&mut self, field: &str, value: T) {
self
.where_cols
.push(format!("{} <> ${}", field, self.next_index()));
self.params.push(Box::new(value.clone()));
}
}
impl QueryBuilderWithSet for UpdateBuilder {
fn set<T: 'static + ToSql + Sync + Clone>(&mut self, field: &str, value: T) {
self
.fields
.push(format!("{} = ${}", field, self.next_index()));
self.params.push(Box::new(value.clone()));
}
fn set_computed(&mut self, field: &str, value: &str) {
self.fields.push(format!("{} = {}", field, value));
}
}
#[cfg(test)]
pub mod test {
use super::*;
#[test]
fn from_scratch() {
let builder = UpdateBuilder::new("publishers");
assert_eq!(builder.get_query(), "UPDATE publishers");
}
#[test]
fn with_fields_and_where() {
let mut builder = UpdateBuilder::new("publishers");
builder.where_eq("trololo", 42);
builder.set("id", 5);
assert_eq!(builder.get_query(), "UPDATE publishers SET id = $2 WHERE trololo = $1");
}
#[test]
fn with_computed_fields_and_where() {
let mut builder = UpdateBuilder::new("publishers");
builder.where_eq("trololo", 42);
builder.set("id", 5);
builder.set_computed("trololo", "md5(42)");
assert_eq!(builder.get_query(), "UPDATE publishers SET id = $2, trololo = md5(42) WHERE trololo = $1");
}
}