1pub mod conditions;
2
3use crate::{SQL, SQLParam, ToSQL};
4
5pub struct CTE {
7 name: &'static str,
8}
9
10pub struct DefinedCTE<'a, V: SQLParam, Q: ToSQL<'a, V>> {
12 name: &'a str,
13 query: Q,
14 _phantom: std::marker::PhantomData<V>,
15}
16
17impl CTE {
18 pub fn r#as<'a, V: SQLParam, Q: ToSQL<'a, V>>(self, query: Q) -> DefinedCTE<'a, V, Q> {
20 DefinedCTE {
21 name: self.name,
22 query,
23 _phantom: std::marker::PhantomData,
24 }
25 }
26}
27
28impl<'a, V: SQLParam, Q: ToSQL<'a, V>> DefinedCTE<'a, V, Q> {
29 pub fn name(&self) -> &'a str {
31 self.name
32 }
33}
34
35impl<'a, V: SQLParam + 'a, Q: ToSQL<'a, V>> ToSQL<'a, V> for DefinedCTE<'a, V, Q> {
36 fn to_sql(&self) -> SQL<'a, V> {
37 SQL::raw(self.name)
38 }
39}
40
41impl<'a, V: SQLParam, Q: ToSQL<'a, V>> DefinedCTE<'a, V, Q> {
42 pub fn definition(&self) -> SQL<'a, V> {
44 SQL::raw(self.name)
45 .append_raw("AS")
46 .append(self.query.to_sql().subquery())
47 }
48}
49
50impl<'a, V: SQLParam, Q: ToSQL<'a, V>> AsRef<DefinedCTE<'a, V, Q>> for DefinedCTE<'a, V, Q> {
51 fn as_ref(&self) -> &DefinedCTE<'a, V, Q> {
52 self
53 }
54}
55
56pub fn cte(name: &'static str) -> CTE {
58 CTE { name }
59}
60
61pub fn with<'a, V: SQLParam + 'a, Q: ToSQL<'a, V>, M: ToSQL<'a, V>>(
63 cte: DefinedCTE<'a, V, Q>,
64 main_query: M,
65) -> SQL<'a, V> {
66 SQL::raw("WITH")
67 .append(cte.definition())
68 .append(main_query.to_sql())
69}
70
71pub fn alias<'a, V: SQLParam + 'a, C: ToSQL<'a, V>>(col: C, alias: &'a str) -> SQL<'a, V> {
72 col.to_sql()
73 .append_raw(" AS ")
74 .append(SQL::<'a, V>::raw(alias))
75}
76
77pub fn count<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(expr: E) -> SQL<'a, V> {
85 create_aggregate_function(expr, "COUNT")
86}
87
88pub fn sum<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(expr: E) -> SQL<'a, V> {
96 create_aggregate_function(expr, "SUM")
97}
98
99pub fn avg<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(expr: E) -> SQL<'a, V> {
107 create_aggregate_function(expr, "AVG")
108}
109
110pub fn min<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(expr: E) -> SQL<'a, V> {
118 create_aggregate_function(expr, "MIN")
119}
120
121pub fn max<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(expr: E) -> SQL<'a, V> {
129 create_aggregate_function(expr, "MAX")
130}
131
132pub fn distinct<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(expr: E) -> SQL<'a, V> {
140 SQL::raw("DISTINCT").append(expr.to_sql())
141}
142
143pub fn coalesce<'a, V: SQLParam + 'a, E: ToSQL<'a, V>, D: ToSQL<'a, V>>(
152 expr: E,
153 default: D,
154) -> SQL<'a, V> {
155 SQL::raw("COALESCE(")
156 .append(expr.to_sql())
157 .append_raw(", ")
158 .append(default.to_sql())
159 .append_raw(")")
160}
161
162fn create_aggregate_function<'a, V: SQLParam + 'a, E: ToSQL<'a, V>>(
164 expr: E,
165 function_name: &'a str,
166) -> SQL<'a, V> {
167 SQL::raw(function_name).append(expr.to_sql().subquery())
168}