Skip to main content

ngb_sqlbuilder/
lib.rs

1use crate::select::Clause;
2use tokio_postgres::types::ToSql;
3
4// type Parameter = (dyn ToSql + Sync);
5
6mod builder;
7mod clause;
8mod condition;
9mod delete;
10mod insert;
11#[allow(dead_code)]
12mod select;
13mod update;
14
15// pub use builder::*;
16// pub use clause::*;
17pub use condition::*;
18pub use delete::*;
19pub use insert::*;
20pub use select::*;
21pub use update::*;
22
23pub struct Raw;
24// #[derive(Debug)]
25pub struct Column;
26// #[derive(Debug)]
27pub struct Select;
28// #[derive(Debug)]
29pub struct From;
30// #[derive(Debug)]
31pub struct Table;
32// #[derive(Debug)]
33// pub struct Final;
34// #[derive(Debug)]
35pub struct Join;
36// #[derive(Debug)]
37
38// #[derive(Debug)]
39pub struct Condition;
40// #[derive(Debug)]
41pub struct Paging;
42
43trait SqlClause<'q> {
44    fn unwrap(self) -> (String, Vec<&'q (dyn ToSql + Sync)>);
45}
46impl<'q> Clause<'q, Column> {
47    pub fn eq<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
48        self.op("=", value)
49    }
50    pub fn neq<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
51        self.op("!=", value)
52    }
53    pub fn lt<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
54        self.op("<", value)
55    }
56    pub fn gt<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
57        self.op(">", value)
58    }
59    pub fn lte<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
60        self.op("<=", value)
61    }
62    pub fn gte<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
63        self.op(">=", value)
64    }
65    pub fn like<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
66        self.op("like", value)
67    }
68    pub fn ilike<T: ToSql + Sync + 'q>(self, value: &'q T) -> Clause<'q, Condition> {
69        self.op("ilike", value)
70    }
71    pub fn between<T: ToSql + Sync + 'q>(self, low: &'q T, high: &'q T) -> Clause<'q, Condition> {
72        let (mut sql, mut params) = self.unwrap();
73        sql.push_str(" between $ and $");
74        params.push(low);
75        params.push(high);
76        Clause::<Condition>::new(sql, params)
77    }
78    pub fn op<T: ToSql + Sync + 'q>(self, op: &str, value: &'q T) -> Clause<'q, Condition> {
79        let (mut sql, mut params) = self.unwrap();
80        sql.push_str(&format!(" {op} $"));
81        params.push(value);
82        Clause::<Condition>::new(sql, params)
83    }
84}
85fn format_col(name: &str) -> String {
86    let mut cast_split = name.split("::");
87    let name = cast_split.next().unwrap_or_default();
88    let mut result = match name.chars().position(|c| c == '.') {
89        Some(dot) => format!("{}.\"{}\"", &name[..dot], name[dot + 1..].trim()),
90        None => format!("\"{}\"", name),
91    };
92    if let Some(cast) = cast_split.next() {
93        result.push_str(&format!("::{}", cast).as_str())
94    }
95    result
96}
97fn format_prim(name: &str) -> String {
98    let name = name.trim();
99    let (col, alias) = {
100        let mut split_as = name.split(" as ");
101        let col_name = split_as.next().unwrap_or_default();
102        let alias = split_as.next();
103        (col_name, alias)
104    };
105
106    let mut col_name = format_col(col);
107
108    if let Some(a) = alias {
109        if a.chars().any(char::is_uppercase) {
110            col_name.push_str(&format!(" as \"{}\"", a));
111        } else {
112            col_name.push_str(&format!(" as {}", a));
113        }
114    }
115    col_name
116}
117fn __cols(sql: &mut String, columns: &[&str]) {
118    let mut not_first = false;
119    for col in columns {
120        if not_first {
121            sql.push_str(", ");
122        }
123        not_first = true;
124        sql.push_str(&format_prim(col));
125    }
126}
127pub fn cols<'q>(columns: &[&str]) -> Clause<'q, Column> {
128    let mut sql = String::new();
129    __cols(&mut sql, columns);
130    Clause::new(sql, vec![])
131}
132fn wrap(s: &str) -> String {
133    format!("\"{}\"", s)
134}
135
136pub fn raw<'q, T>(sql: &str, values: &[&'q (dyn ToSql + Sync)]) -> Clause<'q, T> {
137    Clause::new(sql.to_string(), values.to_vec())
138}
139
140fn __and_col<'q, T>(
141    clause: Clause<'q, T>,
142    name: &str,
143    condition: Clause<'q, Condition>,
144) -> Clause<'q, T> {
145    let (mut sql, mut params) = clause.unwrap();
146    let (cond_sql, cond_params) = condition.unwrap();
147    sql.push_str(" AND ");
148    sql.push_str(&format_col(name));
149    sql.push_str(cond_sql.as_str());
150    params.extend(cond_params);
151    Clause::new(sql, params)
152}
153fn __or_col<'q, T>(
154    clause: Clause<'q, T>,
155    name: &str,
156    condition: Clause<'q, Condition>,
157) -> Clause<'q, T> {
158    let (mut sql, mut params) = clause.unwrap();
159    let (cond_sql, cond_params) = condition.unwrap();
160    sql.push_str(" OR ");
161    sql.push_str(&format_col(name));
162    sql.push_str(cond_sql.as_str());
163    params.extend(cond_params);
164    Clause::new(sql, params)
165}
166
167fn __and_cond<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, T> {
168    let (mut sql, mut params) = clause.unwrap();
169    let (cond_sql, cond_params) = condition.unwrap();
170    sql.push_str(" AND ");
171    sql.push_str(cond_sql.as_str());
172    params.extend(cond_params);
173    Clause::new(sql, params)
174}
175fn __or_cond<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, T> {
176    let (mut sql, mut params) = clause.unwrap();
177    let (cond_sql, cond_params) = condition.unwrap();
178    sql.push_str(" OR ");
179    sql.push_str(cond_sql.as_str());
180    params.extend(cond_params);
181    Clause::new(sql, params)
182}
183
184fn __and_wrap<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
185    let (mut sql, mut params) = clause.unwrap();
186    sql.push_str(" AND (");
187    sql.push_str(&condition.sql);
188    sql.push(')');
189    params.extend(condition.params);
190    Clause::new(sql, params)
191}
192fn __or_wrap<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
193    let (mut sql, mut params) = clause.unwrap();
194    sql.push_str(" OR (");
195    sql.push_str(&condition.sql);
196    sql.push(')');
197    params.extend(condition.params);
198    Clause::new(sql, params)
199}
200fn __condition<'q, T, C>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, C> {
201    let (mut sql, mut params) = clause.unwrap();
202    let (cond_sql, cond_params) = condition.unwrap();
203    sql.push_str(&cond_sql);
204    params.extend_from_slice(&cond_params);
205    Clause::new(sql, params)
206}