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 or_(
190 &self,
191 other: impl $crate::vantage_expressions::Expressive<T>,
192 ) -> $crate::primitives::ConditionGroup<T>
193 where
194 Self: Sized,
195 {
196 $crate::primitives::or_(self.expr(), other.expr())
197 }
198
199 fn and_(
205 &self,
206 other: impl $crate::vantage_expressions::Expressive<T>,
207 ) -> $crate::primitives::ConditionGroup<T>
208 where
209 Self: Sized,
210 {
211 $crate::primitives::and_(self.expr(), other.expr())
212 }
213
214 fn eq(&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 ne(&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 gt(&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 gte(&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 lt(&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 lte(&self, value: 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, value, "{} <= {}",
271 )
272 }
273
274 fn in_(&self, values: impl $crate::vantage_expressions::Expressive<T>) -> $condition
276 where
277 Self: Sized,
278 {
279 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
280 self,
281 values,
282 "{} IN ({})",
283 )
284 }
285
286 fn in_list<V: Into<T> + Clone>(&self, values: &[V]) -> $condition
288 where
289 Self: Sized,
290 T: Clone,
291 {
292 use $crate::vantage_expressions::Expression;
293 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
294 let params: Vec<Expression<T>> = values
295 .iter()
296 .map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
297 .collect();
298 let expr: Expression<T> = Expression::new(
299 "{} IN ({})",
300 vec![
301 ExpressiveEnum::Nested(self.expr()),
302 ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
303 ],
304 );
305 $condition::from_typed(expr)
306 }
307
308 fn not_in(&self, values: impl $crate::vantage_expressions::Expressive<T>) -> $condition
310 where
311 Self: Sized,
312 {
313 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
314 self,
315 values,
316 "{} NOT IN ({})",
317 )
318 }
319
320 fn not_in_list<V: Into<T> + Clone>(&self, values: &[V]) -> $condition
322 where
323 Self: Sized,
324 T: Clone,
325 {
326 use $crate::vantage_expressions::Expression;
327 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
328 let params: Vec<Expression<T>> = values
329 .iter()
330 .map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
331 .collect();
332 let expr: Expression<T> = Expression::new(
333 "{} NOT IN ({})",
334 vec![
335 ExpressiveEnum::Nested(self.expr()),
336 ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
337 ],
338 );
339 $condition::from_typed(expr)
340 }
341
342 fn cast(&self, type_name: &str) -> $condition
344 where
345 Self: Sized,
346 {
347 use $crate::vantage_expressions::Expression;
348 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
349 let expr: Expression<T> = Expression::new(
350 format!("CAST({{}} AS {type_name})"),
351 vec![ExpressiveEnum::Nested(self.expr())],
352 );
353 $condition::from_typed(expr)
354 }
355
356 fn is_null(&self) -> $condition
358 where
359 Self: Sized,
360 {
361 use $crate::vantage_expressions::Expression;
362 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
363 let expr: Expression<T> =
364 Expression::new("{} IS NULL", vec![ExpressiveEnum::Nested(self.expr())]);
365 $condition::from_typed(expr)
366 }
367
368 fn is_not_null(&self) -> $condition
370 where
371 Self: Sized,
372 {
373 use $crate::vantage_expressions::Expression;
374 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
375 let expr: Expression<T> =
376 Expression::new("{} IS NOT NULL", vec![ExpressiveEnum::Nested(self.expr())]);
377 $condition::from_typed(expr)
378 }
379 }
380
381 impl<T, S> $trait_name<T> for S
384 where
385 S: $crate::vantage_expressions::Expressive<T>,
386 T: Into<$any_type> + Send + Clone + 'static,
387 {
388 }
389
390 impl $crate::vantage_expressions::Expressive<$any_type> for $condition {
394 fn expr(&self) -> $crate::vantage_expressions::Expression<$any_type> {
395 self.0.clone()
396 }
397 }
398 };
399}
400
401pub fn build_sql_binary<T, AnyType, Cond>(
405 lhs: &(impl Expressive<T> + ?Sized),
406 rhs: impl Expressive<T>,
407 template: &str,
408) -> Cond
409where
410 T: Into<AnyType> + Send + Clone + 'static,
411 Cond: From<Expression<T>>,
412{
413 let expr: Expression<T> = Expression::new(
414 template,
415 vec![
416 ExpressiveEnum::Nested(lhs.expr()),
417 ExpressiveEnum::Nested(rhs.expr()),
418 ],
419 );
420 Cond::from(expr)
421}