1use crate::select::Clause;
2use tokio_postgres::types::ToSql;
3
4mod builder;
7mod clause;
8mod condition;
9mod delete;
10mod insert;
11#[allow(dead_code)]
12mod select;
13mod update;
14
15pub use condition::*;
18pub use delete::*;
19pub use insert::*;
20pub use select::*;
21pub use update::*;
22
23pub struct Raw;
24pub struct Column;
26pub struct Select;
28pub struct From;
30pub struct Table;
32pub struct Join;
36pub struct Condition;
40pub 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}