sqlink/postgres/
update_builder.rs1use crate::error::Error;
2use crate::postgres::query_table::{QueryTables, QueryTable};
3use crate::postgres::query_field::{QueryWithParams, ParameterValueAsRef};
4use crate::postgres::query_token::{QueryTokens, QueryToken, FormatQueryTup};
5use crate::postgres::query_where::{QueryWheres, WhereOperator};
6use crate::postgres::query_set::{QuerySets};
7use crate::postgres::query_return::{QueryReturns, QueryReturnField};
8
9#[derive(Default, Debug)]
10pub struct SqlUpdate<'a> {
11 _tables: QueryTables, _sets: QuerySets,
13 _wheres: QueryWheres,
14 _returns: QueryReturns,
15 _parameters: Vec<ParameterValueAsRef<'a>>,
16}
17
18impl<'a> SqlUpdate<'a> {
19 pub fn new() -> SqlUpdate<'static> {
20 SqlUpdate::default()
21 }
22 pub fn build(&self) -> Result<QueryWithParams, Error> {
23 let mut param_iter = 1;
24 let built_for_table = self._tables.build(&mut param_iter)?;
25 let built_for_update = self._sets.build_for_update(&mut param_iter)?;
26 let mut vec: Vec<String> = Vec::new();
27 let mut p: Vec<ParameterValueAsRef> = Vec::new();
28 for ploc in built_for_table.parameters_loc {
29 p.push(self._parameters[ploc]);
30 }
31 for ploc in built_for_update.parameters_loc {
32 p.push(self._parameters[ploc]);
33 }
34 vec.push(format!("UPDATE {} SET {}", built_for_table.query, built_for_update.query));
35 if self._wheres.len() > 0 {
36 let built_for_where = self._wheres.build(&mut param_iter)?;
37 vec.push(format!("WHERE {}", built_for_where.query));
38 for ploc in built_for_where.parameters_loc {
39 p.push(self._parameters[ploc]);
40 }
41 }
42 if self._returns.len() > 0 {
43 let built_for_return: String = self._returns.build()?;
44 vec.push(format!("RETURNING {}", built_for_return));
45 }
46
47 Ok(QueryWithParams {
48 query: vec.join(" "),
49 parameters: p,
50 })
51 }
52 pub fn table<S: Into<QueryTable>>(&mut self, table: S) -> &mut Self {
53 self._tables.push(table.into());
54 self
55 }
56 pub fn set<S: Into<String>, T>(&mut self, field: S, param: &'a T) -> &mut Self where T: postgres_types::ToSql + std::marker::Sync + 'a {
57 self._parameters.push(param);
58 self._sets.set((field.into(), QueryTokens(vec![QueryToken::ParameterLoc(self._parameters.len() - 1)])));
59 self
60 }
61 pub fn set_raw<S: Into<String>>(&mut self, field: S, tup: FormatQueryTup<'a>) -> &mut Self{
62 let len = self._parameters.len();
63 self._parameters.extend(tup.1);
64 let qtokens = (tup.0).to_query_tokens(len);
65 self._sets.set((field.into(), qtokens));
66 self
67 }
68 pub fn returning<S: Into<QueryReturnField>>(&mut self, field: S) -> &mut Self {
69 self._returns.push(field.into());
70 self
71 }
72 pub fn and_where(&mut self, ftup: FormatQueryTup<'a>) -> &mut Self {
73 if self._wheres.len() > 0 {
74 self._wheres.push(WhereOperator::And);
75 }
76 let len = self._parameters.len();
77 self._parameters.extend(ftup.1);
78 let qtokens = (ftup.0).to_query_tokens(len);
79 self._wheres.extend(qtokens.into());
80 self
81 }
82 pub fn or_where(&mut self, ftup: FormatQueryTup<'a>) -> &mut Self {
83 if self._wheres.len() > 0 {
84 self._wheres.push(WhereOperator::Or);
85 }
86 let len = self._parameters.len();
87 self._parameters.extend(ftup.1);
88 let qtokens = (ftup.0).to_query_tokens(len);
89 self._wheres.extend(qtokens.into());
90 self
91 }
92 pub fn and_where_open(&mut self) -> &mut Self {
93 if self._wheres.len() > 0 {
94 self._wheres.push(WhereOperator::And);
95 }
96 self._wheres.push(WhereOperator::Open);
97 self
98 }
99 pub fn or_where_open(&mut self) -> &mut Self {
100 if self._wheres.len() > 0 {
101 self._wheres.push(WhereOperator::Or);
102 }
103 self._wheres.push(WhereOperator::Open);
104 self
105 }
106 pub fn where_close(&mut self) -> &mut Self {
107 self._wheres.push(WhereOperator::Close);
108 self
110 }
111 pub fn inner_join<S: Into<QueryTable>>(&mut self, query_table: S, ftup: FormatQueryTup<'a>) -> &mut Self {
112 let len = self._parameters.len();
113 self._parameters.extend(ftup.1);
114 let qtokens = (ftup.0).to_query_tokens(len);
115 self._tables.inner_join(query_table.into());
116 self._tables.on(qtokens.into());
117 self
118 }
119 pub fn left_join<S: Into<QueryTable>>(&mut self, query_table: S, ftup: FormatQueryTup<'a>) -> &mut Self {
120 let len = self._parameters.len();
121 self._parameters.extend(ftup.1);
122 let qtokens = (ftup.0).to_query_tokens(len);
123 self._tables.left_join(query_table.into());
124 self._tables.on(qtokens.into());
125 self
126 }
127 pub fn right_join<S: Into<QueryTable>>(&mut self, query_table: S, ftup: FormatQueryTup<'a>) -> &mut Self {
128 let len = self._parameters.len();
129 self._parameters.extend(ftup.1);
130 let qtokens = (ftup.0).to_query_tokens(len);
131 self._tables.right_join(query_table.into());
132 self._tables.on(qtokens.into());
133 self
134 }
135 pub fn full_join<S: Into<QueryTable>>(&mut self, query_table: S, ftup: FormatQueryTup<'a>) -> &mut Self {
136 let len = self._parameters.len();
137 self._parameters.extend(ftup.1);
138 let qtokens = (ftup.0).to_query_tokens(len);
139 self._tables.full_join(query_table.into());
140 self._tables.on(qtokens.into());
141 self
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use crate::postgres::query_token::{format_query};
148 use super::*;
149 #[test]
150 fn test_update_builder_1() {
151 let mut sqlupdate = SqlUpdate::new();
152 let qbuild = sqlupdate
153 .table("user")
154 .set("age", &1337)
155 .set_raw("name", format_query("LOWER({})".to_owned(), vec![&("foo")]))
156 .and_where(format_query("id = {}".to_owned(), vec![&(1)]))
157 .build().unwrap();
158 assert_eq!(qbuild.query, "UPDATE \"user\" SET \"age\"=$1,\"name\"=LOWER($2) WHERE id = $3");
159 assert_eq!(format!("{:?}", qbuild.parameters), "[1337, \"foo\", 1]");
160 }
161}