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
26pub struct Raw;
27// #[derive(Debug)]
28pub struct Column;
29// #[derive(Debug)]
30pub struct Select;
31// #[derive(Debug)]
32pub struct From;
33// #[derive(Debug)]
34pub struct Table;
35// #[derive(Debug)]
36// pub struct Final;
37// #[derive(Debug)]
38pub struct Join;
39pub struct Condition;
40pub struct Paging;
41
42trait SqlClause<'q> {
43    fn unwrap(self) -> (String, Vec<&'q (dyn ToSql + Sync)>);
44}
45pub trait Build<'q> {
46    fn build(self) -> (String, Vec<&'q (dyn ToSql + Sync)>);
47    // fn build_as_ref(&self) -> (&str, &[&'q (dyn ToSql + Sync)]);
48}
49
50fn format_col(name: &str) -> String {
51    let mut cast_split = name.split("::");
52    let name = cast_split.next().unwrap_or_default();
53    let mut result = match name.chars().position(|c| c == '.') {
54        Some(dot) => format!("{}.\"{}\"", &name[..dot], name[dot + 1..].trim()),
55        None => format!("\"{}\"", name),
56    };
57    if let Some(cast) = cast_split.next() {
58        result.push_str(&format!("::{}", cast).as_str())
59    }
60    result
61}
62fn format_prim(name: &str) -> String {
63    let name = name.trim();
64    let (col, alias) = {
65        let mut split_as = name.split(" as ");
66        let col_name = split_as.next().unwrap_or_default();
67        let alias = split_as.next();
68        (col_name, alias)
69    };
70
71    let mut col_name = format_col(col);
72
73    if let Some(a) = alias {
74        if a.chars().any(char::is_uppercase) {
75            col_name.push_str(&format!(" as \"{}\"", a));
76        } else {
77            col_name.push_str(&format!(" as {}", a));
78        }
79    }
80    col_name
81}
82fn __cols(sql: &mut String, columns: &[&str]) {
83    let mut not_first = false;
84    for col in columns {
85        if not_first {
86            sql.push_str(", ");
87        }
88        not_first = true;
89        sql.push_str(&format_prim(col));
90    }
91}
92pub fn cols<'q>(columns: &[&str]) -> Clause<'q, Column> {
93    let mut sql = String::new();
94    __cols(&mut sql, columns);
95    Clause::new(sql, vec![])
96}
97pub fn func<'q, T, C>(name: &str, clause: Clause<'q, T>) -> Clause<'q, C> {
98    let mut sql = String::from(name);
99    let (cl_sql, cl_params) = clause.unwrap();
100    sql.push('(');
101    sql.push_str(&cl_sql);
102    sql.push(')');
103    Clause::new(sql, cl_params)
104}
105pub fn func_col<'q>(func_name: &str, column: &str) -> Clause<'q, Column> {
106    func(func_name, col(column))
107}
108pub fn avg_col(column: &str) -> Clause<'_, Column> {
109    func("avg", col(column))
110}
111pub fn max_col(column: &str) -> Clause<'_, Column> {
112    func("max", col(column))
113}
114pub fn min_col(column: &str) -> Clause<'_, Column> {
115    func("min", col(column))
116}
117pub fn sum_col(column: &str) -> Clause<'_, Column> {
118    func("sum", col(column))
119}
120fn wrap(s: &str) -> String {
121    format!("\"{}\"", s)
122}
123
124pub fn raw<'q, T>(sql: &str, values: &[&'q (dyn ToSql + Sync)]) -> Clause<'q, T> {
125    Clause::new(sql.to_string(), values.to_vec())
126}
127
128fn __and_col<'q, T>(
129    clause: Clause<'q, T>,
130    name: &str,
131    condition: Clause<'q, Condition>,
132) -> Clause<'q, T> {
133    let (mut sql, mut params) = clause.unwrap();
134    let (cond_sql, cond_params) = condition.unwrap();
135    sql.push_str(" AND ");
136    sql.push_str(&format_col(name));
137    sql.push_str(cond_sql.as_str());
138    params.extend(cond_params);
139    Clause::new(sql, params)
140}
141fn __or_col<'q, T>(
142    clause: Clause<'q, T>,
143    name: &str,
144    condition: Clause<'q, Condition>,
145) -> Clause<'q, T> {
146    let (mut sql, mut params) = clause.unwrap();
147    let (cond_sql, cond_params) = condition.unwrap();
148    sql.push_str(" OR ");
149    sql.push_str(&format_col(name));
150    sql.push_str(cond_sql.as_str());
151    params.extend(cond_params);
152    Clause::new(sql, params)
153}
154
155fn __and_cond<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, T> {
156    let (mut sql, mut params) = clause.unwrap();
157    let (cond_sql, cond_params) = condition.unwrap();
158    sql.push_str(" AND ");
159    sql.push_str(cond_sql.as_str());
160    params.extend(cond_params);
161    Clause::new(sql, params)
162}
163fn __or_cond<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, T> {
164    let (mut sql, mut params) = clause.unwrap();
165    let (cond_sql, cond_params) = condition.unwrap();
166    sql.push_str(" OR ");
167    sql.push_str(cond_sql.as_str());
168    params.extend(cond_params);
169    Clause::new(sql, params)
170}
171
172fn __and_wrap<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
173    let (mut sql, mut params) = clause.unwrap();
174    sql.push_str(" AND (");
175    sql.push_str(&condition.sql);
176    sql.push(')');
177    params.extend(condition.params);
178    Clause::new(sql, params)
179}
180fn __or_wrap<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
181    let (mut sql, mut params) = clause.unwrap();
182    sql.push_str(" OR (");
183    sql.push_str(&condition.sql);
184    sql.push(')');
185    params.extend(condition.params);
186    Clause::new(sql, params)
187}
188fn __condition<'q, T, C>(clause: Clause<'q, T>, condition: Clause<'q, Condition>) -> Clause<'q, C> {
189    let (mut sql, mut params) = clause.unwrap();
190    let (cond_sql, cond_params) = condition.unwrap();
191    sql.push_str(&cond_sql);
192    params.extend_from_slice(&cond_params);
193    Clause::new(sql, params)
194}