use crate::{IntoSqlValue, values::FilterValue};
use super::expr::FilterExpr;
use super::field_ref::FieldRef;
use super::op::FilterOp;
#[derive(Debug, Clone, PartialEq)]
pub struct CoalesceFilter {
pub columns: Vec<&'static str>,
pub op: FilterOp,
pub value: FilterValue,
}
pub trait IntoColumnName {
fn into_column_name(self) -> &'static str;
}
impl IntoColumnName for &'static str {
fn into_column_name(self) -> &'static str {
self
}
}
impl<M, T> IntoColumnName for FieldRef<M, T> {
fn into_column_name(self) -> &'static str {
self.column_name()
}
}
pub fn coalesce<I, C>(columns: I) -> CoalesceExpr
where
I: IntoIterator<Item = C>,
C: IntoColumnName,
{
CoalesceExpr {
columns: columns
.into_iter()
.map(IntoColumnName::into_column_name)
.collect(),
}
}
#[derive(Debug, Clone)]
pub struct CoalesceExpr {
columns: Vec<&'static str>,
}
impl CoalesceExpr {
fn into_filter<V: IntoSqlValue>(self, op: FilterOp, value: V) -> FilterExpr {
FilterExpr::Coalesce(CoalesceFilter {
columns: self.columns,
op,
value: FilterValue::Single(value.into_sql_value()),
})
}
pub fn eq<V: IntoSqlValue>(self, value: V) -> FilterExpr {
self.into_filter(FilterOp::Eq, value)
}
pub fn ne<V: IntoSqlValue>(self, value: V) -> FilterExpr {
self.into_filter(FilterOp::Ne, value)
}
pub fn lt<V: IntoSqlValue>(self, value: V) -> FilterExpr {
self.into_filter(FilterOp::Lt, value)
}
pub fn lte<V: IntoSqlValue>(self, value: V) -> FilterExpr {
self.into_filter(FilterOp::Lte, value)
}
pub fn gt<V: IntoSqlValue>(self, value: V) -> FilterExpr {
self.into_filter(FilterOp::Gt, value)
}
pub fn gte<V: IntoSqlValue>(self, value: V) -> FilterExpr {
self.into_filter(FilterOp::Gte, value)
}
pub fn is_null(self) -> FilterExpr {
FilterExpr::Coalesce(CoalesceFilter {
columns: self.columns,
op: FilterOp::IsNull,
value: FilterValue::None,
})
}
pub fn is_not_null(self) -> FilterExpr {
FilterExpr::Coalesce(CoalesceFilter {
columns: self.columns,
op: FilterOp::IsNotNull,
value: FilterValue::None,
})
}
}