1use qail_core::ast::*;
9use qail_core::transpiler::ToSql;
10
11fn main() {
12 let mut stats_query = Qail::get("whatsapp_messages");
14
15 stats_query.columns.push(Expr::Aggregate {
17 col: "phone_number".to_string(),
18 func: AggregateFunc::Count,
19 distinct: true,
20 filter: None,
21 alias: Some("total_contacts".to_string()),
22 });
23
24 stats_query.columns.push(Expr::Aggregate {
26 col: "*".to_string(),
27 func: AggregateFunc::Count,
28 distinct: false,
29 filter: None,
30 alias: Some("total_messages".to_string()),
31 });
32
33 stats_query.columns.push(Expr::Aggregate {
35 col: "*".to_string(),
36 func: AggregateFunc::Count,
37 distinct: false,
38 filter: Some(vec![
39 Condition {
40 left: Expr::Named("direction".to_string()),
41 op: Operator::Eq,
42 value: Value::String("outbound".to_string()),
43 is_array_unnest: false,
44 },
45 Condition {
46 left: Expr::Named("created_at".to_string()),
47 op: Operator::Gt,
48 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
49 is_array_unnest: false,
50 },
51 ]),
52 alias: Some("messages_sent_24h".to_string()),
53 });
54
55 stats_query.columns.push(Expr::Aggregate {
57 col: "*".to_string(),
58 func: AggregateFunc::Count,
59 distinct: false,
60 filter: Some(vec![
61 Condition {
62 left: Expr::Named("direction".to_string()),
63 op: Operator::Eq,
64 value: Value::String("inbound".to_string()),
65 is_array_unnest: false,
66 },
67 Condition {
68 left: Expr::Named("created_at".to_string()),
69 op: Operator::Gt,
70 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
71 is_array_unnest: false,
72 },
73 ]),
74 alias: Some("messages_received_24h".to_string()),
75 });
76
77 stats_query.columns.push(Expr::Aggregate {
79 col: "*".to_string(),
80 func: AggregateFunc::Count,
81 distinct: false,
82 filter: Some(vec![
83 Condition {
84 left: Expr::Named("direction".to_string()),
85 op: Operator::Eq,
86 value: Value::String("inbound".to_string()),
87 is_array_unnest: false,
88 },
89 Condition {
90 left: Expr::Named("status".to_string()),
91 op: Operator::Eq,
92 value: Value::String("received".to_string()),
93 is_array_unnest: false,
94 },
95 ]),
96 alias: Some("unread_messages".to_string()),
97 });
98
99 stats_query.columns.push(Expr::Aggregate {
101 col: "*".to_string(),
102 func: AggregateFunc::Count,
103 distinct: false,
104 filter: Some(vec![
105 Condition {
106 left: Expr::Named("direction".to_string()),
107 op: Operator::Eq,
108 value: Value::String("outbound".to_string()),
109 is_array_unnest: false,
110 },
111 Condition {
112 left: Expr::Named("created_at".to_string()),
113 op: Operator::Gt,
114 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
115 is_array_unnest: false,
116 },
117 Condition {
118 left: Expr::Named("status".to_string()),
119 op: Operator::In,
120 value: Value::Array(vec![
121 Value::String("delivered".to_string()),
122 Value::String("read".to_string()),
123 ]),
124 is_array_unnest: false,
125 },
126 ]),
127 alias: Some("successful_deliveries_24h".to_string()),
128 });
129
130 let stats_cte = stats_query.to_cte("stats");
132
133 let mut final_query = Qail::get("stats").with_cte(stats_cte);
135 final_query.columns = vec![
136 Expr::Named("total_contacts".to_string()),
137 Expr::Named("total_messages".to_string()),
138 Expr::Named("messages_sent_24h".to_string()),
139 Expr::Named("messages_received_24h".to_string()),
140 Expr::Named("unread_messages".to_string()),
141 Expr::Case {
142 when_clauses: vec![(
143 Condition {
144 left: Expr::Named("messages_sent_24h".to_string()),
145 op: Operator::Gt,
146 value: Value::Int(0),
147 is_array_unnest: false,
148 },
149 Box::new(Expr::Binary {
150 left: Box::new(Expr::Binary {
151 left: Box::new(Expr::Cast {
152 expr: Box::new(Expr::Named("successful_deliveries_24h".to_string())),
153 target_type: "float8".to_string(),
154 alias: None,
155 }),
156 op: BinaryOp::Div,
157 right: Box::new(Expr::Cast {
158 expr: Box::new(Expr::Named("messages_sent_24h".to_string())),
159 target_type: "float8".to_string(),
160 alias: None,
161 }),
162 alias: None,
163 }),
164 op: BinaryOp::Mul,
165 right: Box::new(Expr::Named("100.0".to_string())),
166 alias: None,
167 }),
168 )],
169 else_value: Some(Box::new(Expr::Named("0.0".to_string()))),
170 alias: Some("delivery_rate_24h".to_string()),
171 },
172 ];
173
174 let sql = final_query.to_sql();
176 println!("Generated SQL:\n{}", sql);
177}