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