Skip to main content

ngb_sqlbuilder/
lib.rs

1use tokio_postgres::types::ToSql;
2
3// type Parameter = (dyn ToSql + Sync);
4
5mod builder;
6mod clause;
7mod condition;
8mod delete;
9mod insert;
10#[allow(dead_code)]
11mod select;
12mod update;
13
14mod column;
15#[cfg(feature = "execution")]
16pub mod execution;
17
18// pub use builder::*;
19pub use clause::*;
20pub use condition::*;
21pub use delete::*;
22pub use insert::*;
23pub use select::*;
24pub use update::*;
25// pub use column::*;
26
27pub struct Raw;
28// #[derive(Debug)]
29pub struct Column;
30// #[derive(Debug)]
31pub struct Select;
32// #[derive(Debug)]
33pub struct From;
34// #[derive(Debug)]
35pub struct Table;
36// #[derive(Debug)]
37// pub struct Final;
38// #[derive(Debug)]
39pub struct Join;
40pub struct Condition;
41pub struct Paging;
42
43pub trait SqlClause<'q> {
44    fn unwrap(self) -> (String, Vec<&'q (dyn ToSql + Sync)>);
45    fn unwrap_ref(&self) -> (&str, &[&'q (dyn ToSql + Sync)]);
46}
47pub trait Build<'q> {
48    fn build(self) -> (String, Vec<&'q (dyn ToSql + Sync)>);
49    // fn build_ref(&self) -> (&str, &[&'q (dyn ToSql + Sync)]);
50    // fn inspect(&self);
51}
52
53fn format_col(name: &str) -> String {
54    let mut cast_split = name.split("::");
55    let name = cast_split.next().unwrap_or_default();
56    let mut result = match name.chars().position(|c| c == '.') {
57        Some(dot) => format!("{}.\"{}\"", &name[..dot], name[dot + 1..].trim()),
58        None => format!("\"{}\"", name),
59    };
60    if let Some(cast) = cast_split.next() {
61        result.push_str("::");
62        result.push_str(&cast);
63        // result.push_str(&format!("::{}", cast).as_str())
64    }
65    result
66}
67fn append_wrap(sql: &mut String, value: &str) {
68    sql.push('"');
69    sql.push_str(value);
70    sql.push('"');
71}
72fn append_col(sql: &mut String, expr: &str) {
73    let mut cast_split = expr.split("::");
74    let name = cast_split.next().unwrap_or_default();
75    match name.chars().position(|c| c == '.') {
76        Some(dot) => {
77            sql.push_str(&name[..dot]);
78            sql.push('.');
79            append_wrap(sql, &name[dot + 1..]);
80            // format!("{}.\"{}\"", &name[..dot], name[dot + 1..].trim())
81        }
82        None => {
83            append_wrap(sql, name);
84            // format!("\"{}\"", name)
85        }
86    };
87    if let Some(cast) = cast_split.next() {
88        sql.push_str("::");
89        sql.push_str(cast);
90        // result.push_str(&format!("::{}", cast).as_str())
91    }
92}
93fn split_alias(value: &str) -> (&str, Option<&str>) {
94    let mut split_as = value.split(" as ");
95    let col_name = split_as.next().unwrap_or_default();
96    let alias = split_as.next();
97    (col_name, alias)
98}
99fn format_prim(expr: &str) -> String {
100    // let name = name.trim();
101    // let (col, alias) = {
102    //     let mut split_as = name.split(" as ");
103    //     let col_name = split_as.next().unwrap_or_default();
104    //     let alias = split_as.next();
105    //     (col_name, alias)
106    // };
107    let (col, alias) = split_alias(expr.trim());
108
109    let mut col_name = format_col(col);
110
111    if let Some(a) = alias {
112        // col_name.push_str(" as ");
113        col_name.push(' ');
114        if a.chars().any(char::is_uppercase) {
115            col_name.push_str(&wrap(a));
116            // col_name.push_str(&format!(" as \"{}\"", a));
117        } else {
118            col_name.push_str(&a);
119            // col_name.push_str(&format!(" as {}", a));
120        }
121    }
122    col_name
123}
124fn append_prim(sql: &mut String, expr: &str) {
125    let (col, alias) = split_alias(expr.trim());
126
127    append_col(sql, col.trim());
128
129    if let Some(a) = alias {
130        // sql.push_str(" as ");
131        sql.push(' ');
132        if a.chars().any(char::is_uppercase) {
133            append_wrap(sql, a.trim());
134        } else {
135            sql.push_str(a.trim());
136        }
137    }
138}
139fn __cols(sql: &mut String, columns: &[&str]) {
140    let mut not_first = false;
141    for col in columns {
142        if not_first {
143            sql.push_str(", ");
144        }
145        not_first = true;
146        append_prim(sql, col);
147        // sql.push_str(&format_prim(col));
148    }
149}
150pub fn cols<'q>(columns: &[&str]) -> Clause<'q, Column> {
151    let mut sql = String::new();
152    __cols(&mut sql, columns);
153    Clause::new(sql, vec![])
154}
155pub fn func<'q, T, C>(name: &str, clause: Clause<'q, T>) -> Clause<'q, C> {
156    let mut sql = String::from(name);
157    let (cl_sql, cl_params) = clause.unwrap();
158    sql.push('(');
159    sql.push_str(&cl_sql);
160    sql.push(')');
161    Clause::new(sql, cl_params)
162}
163pub fn func_col<'q>(func_name: &str, column: &str) -> Clause<'q, Column> {
164    func(func_name, col(column))
165}
166pub fn avg_col(column: &str) -> Clause<'_, Column> {
167    func("avg", col(column))
168}
169pub fn max_col(column: &str) -> Clause<'_, Column> {
170    func("max", col(column))
171}
172pub fn min_col(column: &str) -> Clause<'_, Column> {
173    func("min", col(column))
174}
175pub fn sum_col(column: &str) -> Clause<'_, Column> {
176    func("sum", col(column))
177}
178fn wrap(s: &str) -> String {
179    format!("\"{}\"", s)
180}
181pub fn extract_col<'q>(field: &str, from: &str) -> Clause<'q, Column> {
182    let mut sql = String::from("extract(");
183    sql.push_str(field);
184    sql.push_str(" from ");
185    sql.push_str(&format_col(from));
186    sql.push(')');
187    Clause::new(sql, vec![])
188}
189
190pub fn raw<'q, T>(sql: &str, values: &[&'q (dyn ToSql + Sync)]) -> Clause<'q, T> {
191    Clause::new(sql.to_string(), values.to_vec())
192}
193
194fn __and_col<'q, T>(
195    clause: Clause<'q, T>,
196    name: &str,
197    condition: Clause<'q, Condition>,
198) -> Clause<'q, T> {
199    let (mut sql, mut params) = clause.unwrap();
200    let (cond_sql, cond_params) = condition.unwrap();
201    sql.push_str(" AND ");
202    // sql.push_str(&format_col(name));
203    append_col(&mut sql, name);
204    sql.push_str(&cond_sql);
205    params.extend(cond_params);
206    Clause::new(sql, params)
207}
208fn __or_col<'q, T>(
209    clause: Clause<'q, T>,
210    name: &str,
211    condition: Clause<'q, Condition>,
212) -> Clause<'q, T> {
213    let (mut sql, mut params) = clause.unwrap();
214    let (cond_sql, cond_params) = condition.unwrap();
215    sql.push_str(" OR ");
216    // sql.push_str(&format_col(name));
217    append_col(&mut sql, name);
218    sql.push_str(&cond_sql);
219    params.extend(cond_params);
220    Clause::new(sql, params)
221}
222
223// fn __and_cond<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, T> {
224//     let (mut sql, mut params) = clause.unwrap();
225//     let (cond_sql, cond_params) = condition.unwrap();
226//     sql.push_str(" AND ");
227//     sql.push_str(&cond_sql);
228//     params.extend(cond_params);
229//     Clause::new(sql, params)
230// }
231// fn __or_cond<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, T> {
232//     let (mut sql, mut params) = clause.unwrap();
233//     let (cond_sql, cond_params) = condition.unwrap();
234//     sql.push_str(" OR ");
235//     sql.push_str(&cond_sql);
236//     params.extend(cond_params);
237//     Clause::new(sql, params)
238// }
239
240fn __and_nest<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
241    let (mut sql, mut params) = clause.unwrap();
242    sql.push_str(" AND (");
243    sql.push_str(&condition.sql);
244    sql.push(')');
245    params.extend(condition.params);
246    Clause::new(sql, params)
247}
248fn __or_nest<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
249    let (mut sql, mut params) = clause.unwrap();
250    sql.push_str(" OR (");
251    sql.push_str(&condition.sql);
252    sql.push(')');
253    params.extend(condition.params);
254    Clause::new(sql, params)
255}
256fn __condition<'q, T, C>(
257    connector: &str,
258    clause: Clause<'q, T>,
259    condition: Clause<'q, Condition>,
260) -> Clause<'q, C> {
261    let (mut sql, mut params) = clause.unwrap();
262    let (cond_sql, cond_params) = condition.unwrap();
263    sql.push_str(connector);
264    sql.push_str(&cond_sql);
265    params.extend_from_slice(&cond_params);
266    Clause::new(sql, params)
267}
268
269const LOGIC_CONN_NONE: &str = "";
270const LOGIC_CONN_AND: &str = " AND ";
271const LOGIC_CONN_OR: &str = " OR ";