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::*;
17// pub use condition::*;
18pub use insert::*;
19pub use select::*;
20pub use update::*;
21pub use delete::*;
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(self) -> Clause<'q, Condition> {
48        todo!()
49    }
50}
51fn format_col(name: &str) -> String {
52    match name.chars().position(|c| c == '.') {
53        Some(dot) => format!("{}.\"{}\"", &name[..dot], name[dot + 1..].trim()),
54        None => format!("\"{}\"", name),
55    }
56}
57fn format_prim(name: &str) -> String {
58    let (col, alias) = {
59        let mut split_as = name.split(" as ");
60        let col_name = split_as.next().unwrap_or_default();
61        let alias = split_as.next();
62        (col_name, alias)
63    };
64
65    let mut col_name = format_col(col);
66
67    if let Some(a) = alias {
68        if a.chars().any(char::is_uppercase) {
69            col_name.push_str(&format!(" as \"{}\"", a));
70        } else {
71            col_name.push_str(&format!(" as {}", a));
72        }
73    }
74    col_name
75}
76fn __cols(sql: &mut String, columns: &[&str]) {
77    let mut not_first = false;
78    for col in columns {
79        if not_first {
80            sql.push_str(", ");
81        }
82        not_first = true;
83        sql.push_str(&format_prim(col));
84    }
85}
86pub fn cols<'q>(columns: &[&str]) -> Clause<'q, Column> {
87    let mut sql = String::new();
88    __cols(&mut sql, columns);
89    Clause::new(sql, vec![])
90}
91fn wrap(s: &str) -> String {
92    format!("\"{}\"", s)
93}
94pub fn op<'q, T: ToSql + Sync + 'q>(op: &str, value: &'q T) -> Clause<'q, Condition> {
95    Clause::<Condition>::new(format!(" {op} $"), vec![value])
96}
97pub fn eq<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
98    op("=", value)
99}
100
101pub fn lt<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
102    op("<", value)
103}
104
105pub fn gt<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
106    op(">", value)
107}
108
109pub fn lte<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
110    op("<=", value)
111}
112
113pub fn gte<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
114    op(">=", value)
115}
116pub fn like<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
117    op("like", value)
118}
119pub fn ilike<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
120    op("ilike", value)
121}
122
123pub fn between<'q, T: ToSql + Sync + 'q>(low: &'q T, high: &'q T) -> Clause<'q, Condition> {
124    Clause::new(" between $ and $".to_string(), vec![low, high])
125}
126
127pub fn raw<'q, T>(sql: &str, values: &[&'q (dyn ToSql + Sync)]) -> Clause<'q, T> {
128    Clause::new(sql.to_string(), values.to_vec())
129}
130
131fn __and<'q, T>(
132    clause: Clause<'q, T>,
133    name: &str,
134    condition: Clause<'q, Condition>,
135) -> Clause<'q, T> {
136    let (mut sql, mut params) = clause.unwrap();
137    let (cond_sql, cond_params) = condition.unwrap();
138    sql.push_str(" AND ");
139    sql.push_str(&format_col(name));
140    sql.push_str(cond_sql.as_str());
141    params.extend(cond_params);
142    Clause::new(sql, params)
143}
144fn __or<'q, T>(
145    clause: Clause<'q, T>,
146    name: &str,
147    condition: Clause<'q, Condition>,
148) -> Clause<'q, T> {
149    let (mut sql, mut params) = clause.unwrap();
150    let (cond_sql, cond_params) = condition.unwrap();
151    sql.push_str(" OR ");
152    sql.push_str(&format_col(name));
153    sql.push_str(cond_sql.as_str());
154    params.extend(cond_params);
155    Clause::new(sql, params)
156}
157
158fn __and_wrap<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Where>) -> Clause<'q, Where> {
159    let (mut sql, mut params) = clause.unwrap();
160    sql.push_str(" AND (");
161    sql.push_str(&condition.sql);
162    sql.push(')');
163    params.extend(condition.params);
164    Clause::new(sql, params)
165}
166fn __or_wrap<'q, T>(clause: Clause<'q, T>, condition: Clause<'q, Where>) -> Clause<'q, Where> {
167    let (mut sql, mut params) = clause.unwrap();
168    sql.push_str(" OR (");
169    sql.push_str(&condition.sql);
170    sql.push(')');
171    params.extend(condition.params);
172    Clause::new(sql, params)
173}