Skip to main content

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}