#[derive(Debug, Clone)]
pub enum FilterExpr {
Comparison {
column: String,
operator: String,
value: Value,
},
ColumnComparison {
left_column: String,
operator: String,
right_column: String,
},
In { column: String, values: Vec<Value> },
NotIn { column: String, values: Vec<Value> },
InSubquery {
column: String,
subquery_sql: String,
subquery_params: Vec<crate::model::Value>,
},
NotInSubquery {
column: String,
subquery_sql: String,
subquery_params: Vec<crate::model::Value>,
},
And(Box<FilterExpr>, Box<FilterExpr>),
Or(Box<FilterExpr>, Box<FilterExpr>),
IsNull { column: String },
IsNotNull { column: String },
Between {
column: String,
min: Value,
max: Value,
},
Exists {
subquery_sql: String,
subquery_params: Vec<crate::model::Value>,
},
NotExists {
subquery_sql: String,
subquery_params: Vec<crate::model::Value>,
},
}
#[derive(Debug, Clone)]
pub enum Value {
Integer(i64),
BigInt(i128),
Duration(std::time::Duration),
Text(String),
Real(f64),
Boolean(bool),
Bytes(Vec<u8>),
DateTime(chrono::DateTime<chrono::Utc>),
Json(serde_json::Value),
Uuid(uuid::Uuid),
Null,
}
pub trait Subquery {
fn to_subquery_sql(&self) -> (String, Vec<crate::model::Value>);
}
impl FilterExpr {
pub fn and(self, other: FilterExpr) -> Self {
FilterExpr::And(Box::new(self), Box::new(other))
}
pub fn or(self, other: FilterExpr) -> Self {
FilterExpr::Or(Box::new(self), Box::new(other))
}
}
#[derive(Debug, Clone)]
pub enum OrderDirection {
Asc,
Desc,
}
#[derive(Debug, Clone)]
pub struct OrderBy {
pub column: String,
pub direction: OrderDirection,
}
impl OrderBy {
pub fn asc(column: String) -> Self {
Self {
column,
direction: OrderDirection::Asc,
}
}
pub fn desc(column: String) -> Self {
Self {
column,
direction: OrderDirection::Desc,
}
}
pub fn to_sql(&self) -> String {
let dir = match self.direction {
OrderDirection::Asc => "ASC",
OrderDirection::Desc => "DESC",
};
format!("{} {}", self.column, dir)
}
}