ngb_sqlbuilder/column.rs
1#![allow(clippy::wrong_self_convention)]
2
3use crate::{Clause, Column, Condition, SqlClause};
4use tokio_postgres::types::ToSql;
5
6impl<'q> Clause<'q, Column> {
7 /// Add alias to column
8 ///
9 /// # Arguments
10 ///
11 /// * `value`: alias name
12 ///
13 /// returns: Clause<Column>
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// use ngb_sqlbuilder::col;
19 ///
20 /// col("t.ColName").alias("col_name")
21 /// // SQL: t."ColName" as "col_name"
22 /// ```
23 pub fn alias(mut self, value: &str) -> Self {
24 if self.sql.contains(" as ") && !self.sql.ends_with(')') {
25 return self;
26 }
27 self.sql.push_str(" as \"");
28 self.sql.push_str(value);
29 self.sql.push('"');
30 self
31 }
32 /// Add cast statement
33 ///
34 /// # Arguments
35 ///
36 /// * `sql_type`: SQL type
37 ///
38 /// returns: Clause<Column>
39 ///
40 /// # Examples
41 ///
42 /// ```
43 /// use ngb_sqlbuilder::col;
44 ///
45 /// col("t.ColName").cast("text")
46 /// // SQL: t."ColName"::text
47 /// ```
48 pub fn cast(mut self, sql_type: &str) -> Self {
49 if self.sql.contains(' ') || self.sql.contains("::") {
50 self.sql = format!("({})::{}", self.sql, sql_type);
51 } else {
52 self.sql.push_str(&format!("::{}", sql_type));
53 }
54 self
55 }
56 /// Add equal `column = value` comparison
57 ///
58 /// # Arguments
59 ///
60 /// * `value`: value to compare. Will be parameterized to `$n`.
61 ///
62 /// returns: Clause<Condition>
63 ///
64 /// # Examples
65 ///
66 /// ```
67 ///
68 /// ```
69 pub fn eq<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
70 self.op("=", value)
71 }
72 /// Add not equal `column != value` comparison
73 ///
74 /// # Arguments
75 ///
76 /// * `value`: value to compare, will be parameterized to `$n`
77 ///
78 /// returns: Clause<Condition>
79 ///
80 /// # Examples
81 ///
82 /// ```
83 ///
84 /// ```
85 pub fn neq<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
86 self.op("!=", value)
87 }
88 /// Compare `column < value`
89 ///
90 /// # Arguments
91 ///
92 /// * `value`: value to compare, will be parameterized to `$n`
93 ///
94 /// returns: Clause<Condition>
95 ///
96 /// # Examples
97 ///
98 /// ```
99 ///
100 /// ```
101 pub fn lt<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
102 self.op("<", value)
103 }
104 /// Compare `column > value`
105 ///
106 /// # Arguments
107 ///
108 /// * `value`: value to compare, will be parameterized to `$n`
109 ///
110 /// returns: Clause<Condition>
111 ///
112 /// # Examples
113 ///
114 /// ```
115 ///
116 /// ```
117 pub fn gt<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
118 self.op(">", value)
119 }
120 /// Compare `column <= value`
121 ///
122 /// # Arguments
123 ///
124 /// * `value`: value to compare, will be parameterized to `$n`
125 ///
126 /// returns: Clause<Condition>
127 ///
128 /// # Examples
129 ///
130 /// ```
131 ///
132 /// ```
133 pub fn lte<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
134 self.op("<=", value)
135 }
136 /// Compare `column >= value`
137 ///
138 /// # Arguments
139 ///
140 /// * `value`: value to compare, will be parameterized to `$n`
141 ///
142 /// returns: Clause<Condition>
143 ///
144 /// # Examples
145 ///
146 /// ```
147 ///
148 /// ```
149 pub fn gte<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
150 self.op(">=", value)
151 }
152 /// Compare `column like value`
153 ///
154 /// # Arguments
155 ///
156 /// * `value`: value to compare, will be parameterized to `$n`
157 ///
158 /// returns: Clause<Condition>
159 ///
160 /// # Examples
161 ///
162 /// ```
163 ///
164 /// ```
165 pub fn like<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
166 self.op("like", value)
167 }
168 /// Compare `column ilike value`
169 ///
170 /// # Arguments
171 ///
172 /// * `value`: value to compare, will be parameterized to `$n`
173 ///
174 /// returns: Clause<Condition>
175 ///
176 /// # Examples
177 ///
178 /// ```
179 ///
180 /// ```
181 pub fn ilike<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
182 self.op("ilike", value)
183 }
184 /// Compare `column between low and high`
185 ///
186 /// # Arguments
187 ///
188 /// * `low`: bottom limit, will be parameterized to `$n`
189 /// * `high`: top limit, will be parameterized to `$n`
190 ///
191 /// returns: Clause<Condition>
192 ///
193 /// # Examples
194 ///
195 /// ```
196 ///
197 /// ```
198 pub fn between<T: ToSql + Sync + 'q>(self, low: &'q T, high: &'q T) -> Clause<'q, Condition> {
199 let (mut sql, mut params) = self.unwrap();
200 sql.push_str(" between $ and $");
201 params.push(low);
202 params.push(high);
203 Clause::<Condition>::new(sql, params)
204 }
205 /// Custom operator comparison `column op value`
206 ///
207 /// # Arguments
208 ///
209 /// * `op`: operator
210 /// * `value`: value to compare, will be parameterized to `$n`
211 ///
212 /// returns: Clause<Condition>
213 ///
214 /// # Examples
215 ///
216 /// ```
217 ///
218 /// ```
219 pub fn op<T: ToSql + Sync + 'q>(self, op: &str, value: &'q T) -> Clause<'q, Condition> {
220 let (mut sql, mut params) = self.unwrap();
221 sql.push_str(&format!(" {op} $"));
222 params.push(value);
223 Clause::<Condition>::new(sql, params)
224 }
225 pub fn is_true(self) -> Clause<'q, Condition> {
226 self.into()
227 }
228 pub fn is_false(self) -> Clause<'q, Condition> {
229 Clause::new(format!("not {}", &self.sql), self.params)
230 }
231 pub fn is_null(self) -> Clause<'q, Condition> {
232 Clause::new(format!("{} is null", &self.sql), self.params)
233 }
234 pub fn is_not_null(self) -> Clause<'q, Condition> {
235 Clause::new(format!("{} is not null", &self.sql), self.params)
236 }
237
238 /// Add raw, unchecked statement.
239 ///
240 /// # Arguments
241 ///
242 /// * `raw_sql`: SQL statement
243 ///
244 /// returns: Clause<T>
245 ///
246 /// # Examples
247 ///
248 /// ```
249 /// use ngb_sqlbuilder::col;
250 ///
251 /// col("t.ColName").raw("is not null")
252 /// // SQL: t."ColName" is not null
253 /// ```
254 pub fn raw(self, raw_sql: &str) -> Clause<'q, Column> {
255 let (mut sql, params) = self.unwrap();
256 sql.push(' ');
257 sql.push_str(&raw_sql.trim());
258 Clause::new(sql, params)
259 }
260
261 /// Set default value if `null`
262 ///
263 /// # Arguments
264 ///
265 /// * `value`: default value, will be rendered directly, no filter.
266 ///
267 /// returns: Clause<Column>
268 ///
269 /// # Examples
270 ///
271 /// ```
272 /// use ngb_sqlbuilder::col;
273 ///
274 /// col("t.ColName").coalesce_raw("0")
275 /// // SQL: coalesce(t."ColName", 0)
276 ///
277 /// col("t.TextValue").coalesce_raw("'empty'")
278 /// // SQL: coalesce(t."ColName", 'empty')
279 /// ```
280 pub fn coalesce_raw(self, value: &str) -> Self {
281 let (sql, params) = self.unwrap();
282 // let (c_sql, c_params) = value.to_clause::<Column>().unwrap();
283 Clause::new(format!("coalesce({},{})", sql, value), params)
284 }
285 /// Set default value if `null`
286 ///
287 /// # Arguments
288 ///
289 /// * `value`: default value, will be parameterized to `$n`
290 ///
291 /// returns: Clause<Condition>
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// use ngb_sqlbuilder::col;
297 ///
298 /// col("t.ColName").coalesce(0)
299 /// // SQL: coalesce(t."ColName", $n)
300 /// ```
301 pub fn coalesce<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
302 let (sql, mut params) = self.unwrap();
303 params.push(value);
304 Clause::new(format!("coalesce({},$)", sql), params)
305 }
306}