1use vantage_expressions::traits::expressive::ExpressiveEnum;
19use vantage_expressions::{Expression, Expressive};
20
21use crate::primitives::fx::Fx;
22use crate::primitives::identifier::Identifier;
23
24macro_rules! define_sql_condition {
25 ($name:ident, $any_type:ty) => {
26 #[derive(Debug, Clone)]
28 pub struct $name(pub Expression<$any_type>);
29
30 impl $name {
31 pub fn into_expr(self) -> Expression<$any_type> {
32 self.0
33 }
34
35 pub fn from_typed<F>(expr: Expression<F>) -> Self
39 where
40 F: Into<$any_type> + Send + Clone + 'static,
41 {
42 use vantage_expressions::ExpressionMap;
43 Self(expr.map())
44 }
45 }
46
47 impl<F> From<Expression<F>> for $name
50 where
51 F: Into<$any_type> + Send + Clone + 'static,
52 {
53 fn from(expr: Expression<F>) -> Self {
54 Self::from_typed(expr)
55 }
56 }
57
58 impl From<Identifier> for $name {
60 fn from(id: Identifier) -> Self {
61 use vantage_expressions::Expressive;
62 Self(id.expr())
63 }
64 }
65
66 impl From<$name> for Expression<$any_type> {
68 fn from(cond: $name) -> Self {
69 cond.0
70 }
71 }
72
73 impl From<Fx<$any_type>> for $name {
75 fn from(fx: Fx<$any_type>) -> Self {
76 Self(fx.into())
77 }
78 }
79 };
80}
81
82#[cfg(feature = "sqlite")]
83define_sql_condition!(SqliteCondition, crate::sqlite::types::AnySqliteType);
84
85#[cfg(feature = "postgres")]
86define_sql_condition!(PostgresCondition, crate::postgres::types::AnyPostgresType);
87
88#[cfg(feature = "mysql")]
89define_sql_condition!(MysqlCondition, crate::mysql::types::AnyMysqlType);
90
91#[cfg(feature = "mysql")]
93impl From<crate::mysql::statements::primitives::FulltextMatch> for MysqlCondition {
94 fn from(fm: crate::mysql::statements::primitives::FulltextMatch) -> Self {
95 Self(fm.into())
96 }
97}
98
99#[macro_export]
107macro_rules! define_typed_ident {
108 ($struct_name:ident, $fn_name:ident, $any_type:ty, $condition:ty) => {
109 #[derive(Debug, Clone)]
110 pub struct $struct_name($crate::primitives::identifier::Identifier);
111
112 impl $struct_name {
113 pub fn new(name: impl Into<String>) -> Self {
114 Self($crate::primitives::identifier::ident(name))
115 }
116
117 pub fn dot_of(mut self, prefix: impl Into<String>) -> Self {
118 self.0 = self.0.dot_of(prefix);
119 self
120 }
121
122 pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
123 self.0 = self.0.with_alias(alias);
124 self
125 }
126
127 pub fn name(&self) -> String {
128 self.0.name()
129 }
130
131 pub fn alias(&self) -> Option<&str> {
132 self.0.alias()
133 }
134 }
135
136 impl $crate::vantage_expressions::Expressive<$any_type> for $struct_name {
137 fn expr(&self) -> $crate::vantage_expressions::Expression<$any_type> {
138 $crate::vantage_expressions::Expressive::<$any_type>::expr(&self.0)
139 }
140 }
141
142 impl From<$struct_name> for $crate::vantage_expressions::Expression<$any_type> {
143 fn from(id: $struct_name) -> Self {
144 $crate::vantage_expressions::Expressive::<$any_type>::expr(&id.0)
145 }
146 }
147
148 impl From<$struct_name> for $condition {
149 fn from(id: $struct_name) -> Self {
150 Self::from_typed($crate::vantage_expressions::Expressive::<$any_type>::expr(
151 &id.0,
152 ))
153 }
154 }
155
156 pub fn $fn_name(name: impl Into<String>) -> $struct_name {
158 $struct_name::new(name)
159 }
160 };
161}
162
163#[macro_export]
166macro_rules! define_sql_operation {
167 ($trait_name:ident, $condition:ident, $any_type:ty) => {
168 pub trait $trait_name<T>: $crate::vantage_expressions::Expressive<T>
174 where
175 T: Into<$any_type> + Send + Clone + 'static,
176 {
177 fn eq(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
179 where
180 Self: Sized,
181 {
182 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
183 self, value, "{} = {}",
184 )
185 }
186
187 fn ne(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
189 where
190 Self: Sized,
191 {
192 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
193 self, value, "{} != {}",
194 )
195 }
196
197 fn gt(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
199 where
200 Self: Sized,
201 {
202 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
203 self, value, "{} > {}",
204 )
205 }
206
207 fn gte(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
209 where
210 Self: Sized,
211 {
212 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
213 self, value, "{} >= {}",
214 )
215 }
216
217 fn lt(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
219 where
220 Self: Sized,
221 {
222 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
223 self, value, "{} < {}",
224 )
225 }
226
227 fn lte(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
229 where
230 Self: Sized,
231 {
232 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
233 self, value, "{} <= {}",
234 )
235 }
236
237 fn in_(&self, values: impl $crate::vantage_expressions::Expressive<T>) -> $condition
239 where
240 Self: Sized,
241 {
242 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
243 self,
244 values,
245 "{} IN ({})",
246 )
247 }
248
249 fn in_list<V: Into<T> + Clone>(&self, values: &[V]) -> $condition
251 where
252 Self: Sized,
253 T: Clone,
254 {
255 use $crate::vantage_expressions::Expression;
256 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
257 let params: Vec<Expression<T>> = values
258 .iter()
259 .map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
260 .collect();
261 let expr: Expression<T> = Expression::new(
262 "{} IN ({})",
263 vec![
264 ExpressiveEnum::Nested(self.expr()),
265 ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
266 ],
267 );
268 $condition::from_typed(expr)
269 }
270
271 fn cast(&self, type_name: &str) -> $condition
273 where
274 Self: Sized,
275 {
276 use $crate::vantage_expressions::Expression;
277 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
278 let expr: Expression<T> = Expression::new(
279 format!("CAST({{}} AS {type_name})"),
280 vec![ExpressiveEnum::Nested(self.expr())],
281 );
282 $condition::from_typed(expr)
283 }
284
285 fn is_null(&self) -> $condition
287 where
288 Self: Sized,
289 {
290 use $crate::vantage_expressions::Expression;
291 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
292 let expr: Expression<T> =
293 Expression::new("{} IS NULL", vec![ExpressiveEnum::Nested(self.expr())]);
294 $condition::from_typed(expr)
295 }
296
297 fn is_not_null(&self) -> $condition
299 where
300 Self: Sized,
301 {
302 use $crate::vantage_expressions::Expression;
303 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
304 let expr: Expression<T> =
305 Expression::new("{} IS NOT NULL", vec![ExpressiveEnum::Nested(self.expr())]);
306 $condition::from_typed(expr)
307 }
308 }
309
310 impl<T, S> $trait_name<T> for S
313 where
314 S: $crate::vantage_expressions::Expressive<T>,
315 T: Into<$any_type> + Send + Clone + 'static,
316 {
317 }
318
319 impl $crate::vantage_expressions::Expressive<$any_type> for $condition {
323 fn expr(&self) -> $crate::vantage_expressions::Expression<$any_type> {
324 self.0.clone()
325 }
326 }
327 };
328}
329
330pub fn build_sql_binary<T, AnyType, Cond>(
334 lhs: &(impl Expressive<T> + ?Sized),
335 rhs: impl Expressive<T>,
336 template: &str,
337) -> Cond
338where
339 T: Into<AnyType> + Send + Clone + 'static,
340 Cond: From<Expression<T>>,
341{
342 let expr: Expression<T> = Expression::new(
343 template,
344 vec![
345 ExpressiveEnum::Nested(lhs.expr()),
346 ExpressiveEnum::Nested(rhs.expr()),
347 ],
348 );
349 Cond::from(expr)
350}