1use tokio_postgres::types::ToSql;
2
3mod 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
18pub use clause::*;
20pub use condition::*;
21pub use delete::*;
22pub use insert::*;
23pub use select::*;
24pub use update::*;
25pub struct Raw;
28pub struct Column;
30pub struct Select;
32pub struct From;
34pub struct Table;
36pub 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 }
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 }
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 }
82 None => {
83 append_wrap(sql, name);
84 }
86 };
87 if let Some(cast) = cast_split.next() {
88 sql.push_str("::");
89 sql.push_str(cast);
90 }
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 (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(' ');
114 if a.chars().any(char::is_uppercase) {
115 col_name.push_str(&wrap(a));
116 } else {
118 col_name.push_str(&a);
119 }
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(' ');
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 }
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> {
183 func("avg", col(column))
184}
185pub fn avg_col_f64(column: &str) -> Clause<'_, Column> {
202 let mut sql = String::from("avg(");
203 append_col(&mut sql, column);
204 sql.push_str(")::double precision");
205 Clause::new(sql, vec![])
206}
207pub fn max_col(column: &str) -> Clause<'_, Column> {
208 func("max", col(column))
209}
210pub fn min_col(column: &str) -> Clause<'_, Column> {
211 func("min", col(column))
212}
213pub fn sum_col(column: &str) -> Clause<'_, Column> {
214 func("sum", col(column))
215}
216fn wrap(s: &str) -> String {
217 format!("\"{}\"", s)
218}
219pub fn extract_col<'q>(field: &str, from: &str) -> Clause<'q, Column> {
220 let mut sql = String::from("extract(");
221 sql.push_str(field);
222 sql.push_str(" from ");
223 sql.push_str(&format_col(from));
224 sql.push(')');
225 Clause::new(sql, vec![])
226}
227
228pub fn raw<'q, T>(sql: &str, values: &[&'q (dyn ToSql + Sync)]) -> Clause<'q, T> {
229 Clause::new(sql.to_string(), values.to_vec())
230}
231
232fn __and_col<'q, T>(
233 clause: Clause<'q, T>,
234 name: &str,
235 condition: Clause<'q, Condition>,
236) -> Clause<'q, T> {
237 let (mut sql, mut params) = clause.unwrap();
238 let (cond_sql, cond_params) = condition.unwrap();
239 sql.push_str(" AND ");
240 append_col(&mut sql, name);
242 sql.push_str(&cond_sql);
243 params.extend(cond_params);
244 Clause::new(sql, params)
245}
246fn __or_col<'q, T>(
247 clause: Clause<'q, T>,
248 name: &str,
249 condition: Clause<'q, Condition>,
250) -> Clause<'q, T> {
251 let (mut sql, mut params) = clause.unwrap();
252 let (cond_sql, cond_params) = condition.unwrap();
253 sql.push_str(" OR ");
254 append_col(&mut sql, name);
256 sql.push_str(&cond_sql);
257 params.extend(cond_params);
258 Clause::new(sql, params)
259}
260
261fn __and_nest<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
279 let (mut sql, mut params) = clause.unwrap();
280 sql.push_str(" AND (");
281 sql.push_str(&condition.sql);
282 sql.push(')');
283 params.extend(condition.params);
284 Clause::new(sql, params)
285}
286fn __or_nest<'q, T1, T2, R>(clause: Clause<'q, T1>, condition: Clause<'q, T2>) -> Clause<'q, R> {
287 let (mut sql, mut params) = clause.unwrap();
288 sql.push_str(" OR (");
289 sql.push_str(&condition.sql);
290 sql.push(')');
291 params.extend(condition.params);
292 Clause::new(sql, params)
293}
294fn __condition<'q, T, C>(
295 connector: &str,
296 clause: Clause<'q, T>,
297 condition: Clause<'q, Condition>,
298) -> Clause<'q, C> {
299 let (mut sql, mut params) = clause.unwrap();
300 let (cond_sql, cond_params) = condition.unwrap();
301 sql.push_str(connector);
302 sql.push_str(&cond_sql);
303 params.extend_from_slice(&cond_params);
304 Clause::new(sql, params)
305}
306
307const LOGIC_CONN_NONE: &str = "";
308const LOGIC_CONN_AND: &str = " AND ";
309const LOGIC_CONN_OR: &str = " OR ";