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
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]
158macro_rules! define_sql_operation {
159 ($trait_name:ident, $condition:ident, $any_type:ty) => {
160 pub trait $trait_name<T>: $crate::vantage_expressions::Expressive<T>
166 where
167 T: Into<$any_type> + Send + Clone + 'static,
168 {
169 fn eq(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
171 where
172 Self: Sized,
173 {
174 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
175 self, value, "{} = {}",
176 )
177 }
178
179 fn ne(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
181 where
182 Self: Sized,
183 {
184 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
185 self, value, "{} != {}",
186 )
187 }
188
189 fn gt(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
191 where
192 Self: Sized,
193 {
194 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
195 self, value, "{} > {}",
196 )
197 }
198
199 fn gte(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
201 where
202 Self: Sized,
203 {
204 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
205 self, value, "{} >= {}",
206 )
207 }
208
209 fn lt(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
211 where
212 Self: Sized,
213 {
214 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
215 self, value, "{} < {}",
216 )
217 }
218
219 fn lte(&self, value: impl $crate::vantage_expressions::Expressive<T>) -> $condition
221 where
222 Self: Sized,
223 {
224 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
225 self, value, "{} <= {}",
226 )
227 }
228
229 fn in_(&self, values: impl $crate::vantage_expressions::Expressive<T>) -> $condition
231 where
232 Self: Sized,
233 {
234 $crate::condition::build_sql_binary::<T, $any_type, $condition>(
235 self,
236 values,
237 "{} IN ({})",
238 )
239 }
240
241 fn in_list<V: Into<T> + Clone>(&self, values: &[V]) -> $condition
243 where
244 Self: Sized,
245 T: Clone,
246 {
247 use $crate::vantage_expressions::Expression;
248 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
249 let params: Vec<Expression<T>> = values
250 .iter()
251 .map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
252 .collect();
253 let expr: Expression<T> = Expression::new(
254 "{} IN ({})",
255 vec![
256 ExpressiveEnum::Nested(self.expr()),
257 ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
258 ],
259 );
260 $condition::from_typed(expr)
261 }
262
263 fn cast(&self, type_name: &str) -> $condition
265 where
266 Self: Sized,
267 {
268 use $crate::vantage_expressions::Expression;
269 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
270 let expr: Expression<T> = Expression::new(
271 format!("CAST({{}} AS {type_name})"),
272 vec![ExpressiveEnum::Nested(self.expr())],
273 );
274 $condition::from_typed(expr)
275 }
276
277 fn is_null(&self) -> $condition
279 where
280 Self: Sized,
281 {
282 use $crate::vantage_expressions::Expression;
283 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
284 let expr: Expression<T> =
285 Expression::new("{} IS NULL", vec![ExpressiveEnum::Nested(self.expr())]);
286 $condition::from_typed(expr)
287 }
288
289 fn is_not_null(&self) -> $condition
291 where
292 Self: Sized,
293 {
294 use $crate::vantage_expressions::Expression;
295 use $crate::vantage_expressions::traits::expressive::ExpressiveEnum;
296 let expr: Expression<T> =
297 Expression::new("{} IS NOT NULL", vec![ExpressiveEnum::Nested(self.expr())]);
298 $condition::from_typed(expr)
299 }
300 }
301
302 impl<T, S> $trait_name<T> for S
305 where
306 S: $crate::vantage_expressions::Expressive<T>,
307 T: Into<$any_type> + Send + Clone + 'static,
308 {
309 }
310
311 impl $crate::vantage_expressions::Expressive<$any_type> for $condition {
315 fn expr(&self) -> $crate::vantage_expressions::Expression<$any_type> {
316 self.0.clone()
317 }
318 }
319 };
320}
321
322pub fn build_sql_binary<T, AnyType, Cond>(
326 lhs: &(impl Expressive<T> + ?Sized),
327 rhs: impl Expressive<T>,
328 template: &str,
329) -> Cond
330where
331 T: Into<AnyType> + Send + Clone + 'static,
332 Cond: From<Expression<T>>,
333{
334 let expr: Expression<T> = Expression::new(
335 template,
336 vec![
337 ExpressiveEnum::Nested(lhs.expr()),
338 ExpressiveEnum::Nested(rhs.expr()),
339 ],
340 );
341 Cond::from(expr)
342}