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
48 where
49 F: Into<$any_type> + Send + Clone + 'static,
50 {
51 fn from(expr: Expression<F>) -> Self {
52 Self::from_typed(expr)
53 }
54 }
55
56 impl From<Identifier> for $name {
57 fn from(id: Identifier) -> Self {
58 use vantage_expressions::Expressive;
59 Self(id.expr())
60 }
61 }
62
63 impl From<$name> for Expression<$any_type> {
64 fn from(cond: $name) -> Self {
65 cond.0
66 }
67 }
68
69 impl From<Fx<$any_type>> for $name {
70 fn from(fx: Fx<$any_type>) -> Self {
71 Self(fx.into())
72 }
73 }
74 };
75}
76
77#[cfg(feature = "sqlite")]
78define_sql_condition!(SqliteCondition, crate::sqlite::types::AnySqliteType);
79
80#[cfg(feature = "postgres")]
81define_sql_condition!(PostgresCondition, crate::postgres::types::AnyPostgresType);
82
83#[cfg(feature = "mysql")]
84define_sql_condition!(MysqlCondition, crate::mysql::types::AnyMysqlType);
85
86#[cfg(feature = "mysql")]
87impl From<crate::mysql::statements::primitives::FulltextMatch> for MysqlCondition {
88 fn from(fm: crate::mysql::statements::primitives::FulltextMatch) -> Self {
89 Self(fm.into())
90 }
91}
92
93#[macro_export]
99macro_rules! define_typed_ident {
100 ($struct_name:ident, $fn_name:ident, $any_type:ty, $condition:ty) => {
101 #[derive(Debug, Clone)]
102 pub struct $struct_name($crate::primitives::identifier::Identifier);
103
104 impl $struct_name {
105 pub fn new(name: impl Into<String>) -> Self {
106 Self($crate::primitives::identifier::ident(name))
107 }
108
109 pub fn dot_of(mut self, prefix: impl Into<String>) -> Self {
110 self.0 = self.0.dot_of(prefix);
111 self
112 }
113
114 pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
115 self.0 = self.0.with_alias(alias);
116 self
117 }
118
119 pub fn name(&self) -> String {
120 self.0.name()
121 }
122
123 pub fn alias(&self) -> Option<&str> {
124 self.0.alias()
125 }
126 }
127
128 impl $crate::vantage_expressions::Expressive<$any_type> for $struct_name {
129 fn expr(&self) -> $crate::vantage_expressions::Expression<$any_type> {
130 $crate::vantage_expressions::Expressive::<$any_type>::expr(&self.0)
131 }
132 }
133
134 impl From<$struct_name> for $crate::vantage_expressions::Expression<$any_type> {
135 fn from(id: $struct_name) -> Self {
136 $crate::vantage_expressions::Expressive::<$any_type>::expr(&id.0)
137 }
138 }
139
140 impl From<$struct_name> for $condition {
141 fn from(id: $struct_name) -> Self {
142 Self::from_typed($crate::vantage_expressions::Expressive::<$any_type>::expr(
143 &id.0,
144 ))
145 }
146 }
147
148 pub fn $fn_name(name: impl Into<String>) -> $struct_name {
150 $struct_name::new(name)
151 }
152 };
153}
154
155#[macro_export]
156macro_rules! define_sql_operation {
157 ($trait_name:ident, $condition:ident, $any_type:ty) => {
158 pub trait $trait_name<T>: $crate::vantage_expressions::Expressive<T>
164 where
165 T: Into<$any_type> + Send + Clone + 'static,
166 {
167 fn or_(
180 &self,
181 other: impl $crate::vantage_expressions::Expressive<T>,
182 ) -> $crate::primitives::ConditionGroup<T>
183 where
184 Self: Sized,
185 {
186 $crate::primitives::or_(self.expr(), other.expr())
187 }
188
189 fn and_(
195 &self,
196 other: impl $crate::vantage_expressions::Expressive<T>,
197 ) -> $crate::primitives::ConditionGroup<T>
198 where
199 Self: Sized,
200 {
201 $crate::primitives::and_(self.expr(), other.expr())
202 }
203
204 fn eq(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
206 where
207 Self: Sized,
208 {
209 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
210 self, value, "{} = {}",
211 )
212 }
213
214 fn ne(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
216 where
217 Self: Sized,
218 {
219 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
220 self, value, "{} != {}",
221 )
222 }
223
224 fn gt(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
226 where
227 Self: Sized,
228 {
229 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
230 self, value, "{} > {}",
231 )
232 }
233
234 fn gte(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
236 where
237 Self: Sized,
238 {
239 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
240 self, value, "{} >= {}",
241 )
242 }
243
244 fn lt(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
246 where
247 Self: Sized,
248 {
249 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
250 self, value, "{} < {}",
251 )
252 }
253
254 fn lte(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
256 where
257 Self: Sized,
258 {
259 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
260 self, value, "{} <= {}",
261 )
262 }
263
264 fn in_(&self, values: impl $crate::vantage_expressions::Expressive<T>) -> $condition
266 where
267 Self: Sized,
268 {
269 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
270 self,
271 values,
272 "{} IN ({})",
273 )
274 }
275
276 fn in_list<V: Into<T> + Clone>(&self, values: &[V]) -> $condition
278 where
279 Self: Sized,
280 T: Clone,
281 {
282 use $crate::vantage_expressions::Expression;
283 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
284 let params: Vec<Expression<T>> = values
285 .iter()
286 .map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
287 .collect();
288 let expr: Expression<T> = Expression::new(
289 "{} IN ({})",
290 vec![
291 ExpressiveEnum::Nested(self.expr()),
292 ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
293 ],
294 );
295 $condition::from_typed(expr)
296 }
297
298 fn not_in(&self, values: impl $crate::vantage_expressions::Expressive<T>) -> $condition
300 where
301 Self: Sized,
302 {
303 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
304 self,
305 values,
306 "{} NOT IN ({})",
307 )
308 }
309
310 fn not_in_list<V: Into<T> + Clone>(&self, values: &[V]) -> $condition
312 where
313 Self: Sized,
314 T: Clone,
315 {
316 use $crate::vantage_expressions::Expression;
317 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
318 let params: Vec<Expression<T>> = values
319 .iter()
320 .map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
321 .collect();
322 let expr: Expression<T> = Expression::new(
323 "{} NOT IN ({})",
324 vec![
325 ExpressiveEnum::Nested(self.expr()),
326 ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
327 ],
328 );
329 $condition::from_typed(expr)
330 }
331
332 fn cast(&self, type_name: &str) -> $condition
334 where
335 Self: Sized,
336 {
337 use $crate::vantage_expressions::Expression;
338 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
339 let expr: Expression<T> = Expression::new(
340 format!("CAST({{}} AS {type_name})"),
341 vec![ExpressiveEnum::Nested(self.expr())],
342 );
343 $condition::from_typed(expr)
344 }
345
346 fn is_null(&self) -> $condition
348 where
349 Self: Sized,
350 {
351 use $crate::vantage_expressions::Expression;
352 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
353 let expr: Expression<T> =
354 Expression::new("{} IS NULL", vec![ExpressiveEnum::Nested(self.expr())]);
355 $condition::from_typed(expr)
356 }
357
358 fn is_not_null(&self) -> $condition
360 where
361 Self: Sized,
362 {
363 use $crate::vantage_expressions::Expression;
364 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
365 let expr: Expression<T> =
366 Expression::new("{} IS NOT NULL", vec![ExpressiveEnum::Nested(self.expr())]);
367 $condition::from_typed(expr)
368 }
369 }
370
371 impl<T, S> $trait_name<T> for S
374 where
375 S: $crate::vantage_expressions::Expressive<T>,
376 T: Into<$any_type> + Send + Clone + 'static,
377 {
378 }
379
380 impl $crate::vantage_expressions::Expressive<$any_type> for $condition {
384 fn expr(&self) -> $crate::vantage_expressions::Expression<$any_type> {
385 self.0.clone()
386 }
387 }
388 };
389}
390
391pub fn build_sql_binary<T, AnyType, Cond>(
395 lhs: &(impl Expressive<T> + ?Sized),
396 rhs: impl Expressive<T>,
397 template: &str,
398) -> Cond
399where
400 T: Into<AnyType> + Send + Clone + 'static,
401 Cond: From<Expression<T>>,
402{
403 let expr: Expression<T> = Expression::new(
404 template,
405 vec![
406 ExpressiveEnum::Nested(lhs.expr()),
407 ExpressiveEnum::Nested(rhs.expr()),
408 ],
409 );
410 Cond::from(expr)
411}