good_ormning/sqlite/query/
helpers.rs1use {
2 super::expr::{
3 BinOp,
4 ComputeType,
5 Expr,
6 Binding,
7 },
8 crate::sqlite::{
9 schema::field::Field,
10 types::{
11 SimpleSimpleType,
12 SimpleType,
13 Type,
14 },
15 },
16 flowcontrol::shed,
17};
18
19pub fn set_field(param_name: impl Into<String>, f: &Field) -> (Field, Expr) {
22 (f.clone(), field_param(param_name, f))
23}
24
25pub fn field_param(param_name: impl Into<String>, f: &Field) -> Expr {
27 Expr::Param {
28 name: param_name.into(),
29 type_: f.type_.type_.clone(),
30 }
31}
32
33pub fn expr_field_eq(param_name: impl Into<String>, f: &Field) -> Expr {
36 Expr::BinOp {
37 left: Box::new(Expr::Binding(Binding::field(f))),
38 op: BinOp::Equals,
39 right: Box::new(Expr::Param {
40 name: param_name.into(),
41 type_: f.type_.type_.clone(),
42 }),
43 }
44}
45
46pub fn expr_field_gt(param_name: impl Into<String>, f: &Field) -> Expr {
49 Expr::BinOp {
50 left: Box::new(Expr::Binding(Binding::field(f))),
51 op: BinOp::GreaterThan,
52 right: Box::new(Expr::Param {
53 name: param_name.into(),
54 type_: f.type_.type_.clone(),
55 }),
56 }
57}
58
59pub fn expr_field_gte(param_name: impl Into<String>, f: &Field) -> Expr {
62 Expr::BinOp {
63 left: Box::new(Expr::Binding(Binding::field(f))),
64 op: BinOp::GreaterThanEqualTo,
65 right: Box::new(Expr::Param {
66 name: param_name.into(),
67 type_: f.type_.type_.clone(),
68 }),
69 }
70}
71
72pub fn expr_field_lt(param_name: impl Into<String>, f: &Field) -> Expr {
75 Expr::BinOp {
76 left: Box::new(Expr::Binding(Binding::field(f))),
77 op: BinOp::LessThan,
78 right: Box::new(Expr::Param {
79 name: param_name.into(),
80 type_: f.type_.type_.clone(),
81 }),
82 }
83}
84
85pub fn expr_field_lte(param_name: impl Into<String>, f: &Field) -> Expr {
88 Expr::BinOp {
89 left: Box::new(Expr::Binding(Binding::field(f))),
90 op: BinOp::LessThanEqualTo,
91 right: Box::new(Expr::Param {
92 name: param_name.into(),
93 type_: f.type_.type_.clone(),
94 }),
95 }
96}
97
98pub fn expr_and(exprs: Vec<Expr>) -> Expr {
100 Expr::BinOpChain {
101 op: BinOp::And,
102 exprs: exprs,
103 }
104}
105
106pub fn expr_or(exprs: Vec<Expr>) -> Expr {
108 Expr::BinOpChain {
109 op: BinOp::Or,
110 exprs: exprs,
111 }
112}
113
114#[cfg(feature = "chrono")]
115pub fn as_utc_chrono(expr: Expr) -> Expr {
116 return Expr::Call {
117 func: "strftime".to_string(),
118 args: vec![Expr::LitString("%Y-%m-%dT%H:%M:%f".to_string()), expr],
119 compute_type: ComputeType::new(|ctx, path, args| {
120 shed!{
121 let arg = args.get(1).unwrap();
122 let Some(type_) = arg.0.iter().next() else {
123 break;
124 };
125 if !matches!(type_.1.type_.type_, SimpleSimpleType::FixedOffsetTimeMsChrono) {
126 ctx
127 .errs
128 .err(
129 path,
130 format!(
131 "This method only operates on fixed-offset timestamps, but the argument is of type {:?}",
132 type_.1.type_.type_
133 ),
134 );
135 }
136 };
137 return Some(Type {
138 type_: SimpleType {
139 type_: SimpleSimpleType::UtcTimeMsChrono,
140 custom: None,
141 },
142 opt: false,
143 array: false,
144 });
145 }),
146 }
147}
148
149pub fn fn_min(expr: Expr) -> Expr {
150 return Expr::Call {
151 func: "min".to_string(),
152 args: vec![expr],
153 compute_type: ComputeType::new(|ctx, path, args| {
154 let Some(t) = args.get(0).unwrap().assert_scalar(&mut ctx.errs, path) else {
155 return None;
156 };
157 return Some(t.1);
158 }),
159 }
160}
161
162pub fn fn_max(expr: Expr) -> Expr {
163 return Expr::Call {
164 func: "max".to_string(),
165 args: vec![expr],
166 compute_type: ComputeType::new(|ctx, path, args| {
167 let Some(t) = args.get(0).unwrap().assert_scalar(&mut ctx.errs, path) else {
168 return None;
169 };
170 return Some(t.1);
171 }),
172 }
173}
174
175pub fn fn_avg(expr: Expr) -> Expr {
176 return Expr::Call {
177 func: "avg".to_string(),
178 args: vec![expr],
179 compute_type: ComputeType::new(|ctx, path, args| {
180 let Some(t) = args.get(0).unwrap().assert_scalar(&mut ctx.errs, path) else {
181 return None;
182 };
183 return Some(t.1);
184 }),
185 }
186}
187
188pub fn fn_count(expr: Expr) -> Expr {
189 return Expr::Call {
190 func: "count".to_string(),
191 args: vec![expr],
192 compute_type: ComputeType::new(|_ctx, _path, _args| {
193 return Some(Type {
194 type_: SimpleType {
195 type_: SimpleSimpleType::I64,
196 custom: None,
197 },
198 opt: false,
199 array: false,
200 });
201 }),
202 }
203}