1use crate::select::Clause;
2use tokio_postgres::types::ToSql;
3
4mod builder;
7mod clause;
8mod condition;
9mod insert;
10#[allow(dead_code)]
11mod select;
12mod update;
13
14pub use insert::*;
18pub use update::*;
19pub use select::*;
20
21pub struct Raw;
22pub struct Column;
24pub struct Select;
26pub struct From;
28pub struct Table;
30pub struct Final;
32pub struct Join;
34pub struct Condition;
38pub struct Paging;
40
41trait SqlClause<'q> {
42 fn get(self) -> (String, Vec<&'q (dyn ToSql + Sync)>);
43}
44fn format_col(name: &str) -> String {
49 match name.chars().position(|c| c == '.') {
50 Some(dot) => format!("{}.\"{}\"", &name[..dot], name[dot + 1..].trim()),
51 None => format!("\"{}\"", name),
52 }
53}
54fn format_prim(name: &str) -> String {
55 let (col, alias) = {
56 let mut split_as = name.split(" as ");
57 let col_name = split_as.next().unwrap_or_default();
58 let alias = split_as.next();
59 (col_name, alias)
60 };
61
62 let mut col_name = format_col(col);
63
64 if let Some(a) = alias {
65 if a.chars().any(char::is_uppercase) {
66 col_name.push_str(&format!(" as \"{}\"", a));
67 } else {
68 col_name.push_str(&format!(" as {}", a));
69 }
70 }
71 col_name
72}
73fn __cols(sql: &mut String, columns: &[&str]) {
74 let mut not_first = false;
75 for col in columns {
76 if not_first {
77 sql.push_str(", ");
78 }
79 not_first = true;
80 sql.push_str(&format_prim(col));
81 }
82}
83pub fn cols<'q>(columns: &[&str]) -> Clause<'q, Column> {
84 let mut sql = String::new();
85 __cols(&mut sql, columns);
86 Clause::new(sql, vec![])
87}
88fn wrap(s: &str) -> String {
89 format!("\"{}\"", s)
90}
91pub fn op<'q, T: ToSql + Sync + 'q>(op: &str, value: &'q T) -> Clause<'q, Condition> {
92 Clause::<Condition>::new(format!(" {op} $"), vec![value])
93}
94
95pub fn eq<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
96 op("=", value)
97}
98
99pub fn lt<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
100 op("<", value)
101}
102
103pub fn gt<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
104 op(">", value)
105}
106
107pub fn lte<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
108 op("<=", value)
109}
110
111pub fn gte<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
112 op(">=", value)
113}
114pub fn like<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
115 op("like", value)
116}
117pub fn ilike<'q, T: ToSql + Sync + 'q>(value: &'q T) -> Clause<'q, Condition> {
118 op("ilike", value)
119}
120
121pub fn between<'q, T: ToSql + Sync + 'q>(low: &'q T, high: &'q T) -> Clause<'q, Condition> {
122 Clause::new(" between $ and $".to_string(), vec![low, high])
123 }
129
130pub fn raw<'q, T>(sql: &str, values: &[&'q (dyn ToSql + Sync)]) -> Clause<'q, T> {
131 Clause::new(sql.to_string(), values.to_vec())
132}