Skip to main content

ngb_sqlbuilder/
clause.rs

1use crate::SqlClause;
2use std::marker::PhantomData;
3use tokio_postgres::types::ToSql;
4
5#[derive(Debug, Clone)]
6pub struct Clause<'q, T> {
7    pub(crate) sql: String,
8    pub(crate) params: Vec<&'q (dyn ToSql + Sync)>,
9    _ph: PhantomData<T>,
10}
11impl<'q, T> Clause<'q, T> {
12    pub(crate) fn new(sql: String, params: Vec<&'q (dyn ToSql + Sync)>) -> Self {
13        Self {
14            sql,
15            params,
16            _ph: PhantomData,
17        }
18    }
19    // pub fn alias(mut self, name: &str) -> Self {
20    //     self.sql.push_str(format!(" as \"{}\"", name).as_str());
21    //     self
22    // }
23    /// Build and compile query into SQL syntax with numbered parameters
24    pub fn build(self) -> (String, Vec<&'q (dyn ToSql + Sync)>) {
25        let init_capacity = self.sql.len() + self.params.len();
26        let mut result = String::with_capacity(init_capacity);
27        let mut start = 0;
28        let mut count = 1;
29        for (i, _) in self.sql.match_indices("$") {
30            result.push_str(&self.sql[start..i]);
31            result.push_str(&format!("${count}"));
32            count += 1;
33            start = i + 1;
34        }
35        result.push_str(&self.sql[start..]);
36        (result, self.params)
37    }
38    pub fn this(self) -> Self {
39        self
40    }
41
42    pub fn into<C>(self) -> Clause<'q, C> {
43        Clause::new(self.sql, self.params)
44    }
45    pub fn combine_raw(self, raw_sql: &str, params: &[&'q (dyn ToSql + Sync)]) -> Self {
46        let (mut s, mut p) = self.unwrap();
47        s.push(' ');
48        s.push_str(&raw_sql.trim());
49        p.extend_from_slice(params);
50        Self::new(s, p)
51    }
52}