use crate::value::Value;
#[derive(Debug, Clone, Default)]
pub struct Query {
pub sql: String,
pub bindings: Vec<Value>,
}
impl Query {
pub fn new(sql: impl Into<String>) -> Self {
Self { sql: sql.into(), bindings: vec![] }
}
pub fn bind(mut self, val: impl Into<Value>) -> Self {
self.bindings.push(val.into());
self
}
}
#[derive(Debug, Clone, Default)]
pub struct QueryBuilder {
pub table: String,
pub operation: Operation,
pub conditions: Vec<Condition>,
pub order_by: Vec<OrderBy>,
pub limit: Option<u64>,
pub offset: Option<u64>,
pub columns: Vec<String>,
pub values: Vec<(String, Value)>,
}
#[derive(Debug, Clone, Default)]
pub enum Operation {
#[default]
Select,
Insert,
Update,
Delete,
Count,
}
#[derive(Debug, Clone)]
pub struct Condition {
pub column: String,
pub op: CondOp,
pub value: Value,
pub conjunction: Conjunction,
}
#[derive(Debug, Clone, Default)]
pub enum Conjunction {
#[default]
And,
Or,
}
#[derive(Debug, Clone)]
pub enum CondOp {
Eq,
Ne,
Gt,
Gte,
Lt,
Lte,
Like,
ILike,
In,
NotIn,
IsNull,
IsNotNull,
}
#[derive(Debug, Clone)]
pub struct OrderBy {
pub column: String,
pub direction: Direction,
}
#[derive(Debug, Clone, Default)]
pub enum Direction {
#[default]
Asc,
Desc,
}
impl QueryBuilder {
pub fn table(name: impl Into<String>) -> Self {
Self { table: name.into(), ..Default::default() }
}
pub fn select(mut self, cols: Vec<impl Into<String>>) -> Self {
self.columns = cols.into_iter().map(|c| c.into()).collect();
self
}
pub fn r#where(mut self, col: impl Into<String>, op: CondOp, val: impl Into<Value>) -> Self {
self.conditions.push(Condition {
column: col.into(),
op,
value: val.into(),
conjunction: Conjunction::And,
});
self
}
pub fn or_where(mut self, col: impl Into<String>, op: CondOp, val: impl Into<Value>) -> Self {
self.conditions.push(Condition {
column: col.into(),
op,
value: val.into(),
conjunction: Conjunction::Or,
});
self
}
pub fn order_by(mut self, col: impl Into<String>, dir: Direction) -> Self {
self.order_by.push(OrderBy { column: col.into(), direction: dir });
self
}
pub fn limit(mut self, n: u64) -> Self {
self.limit = Some(n);
self
}
pub fn offset(mut self, n: u64) -> Self {
self.offset = Some(n);
self
}
pub fn set(mut self, col: impl Into<String>, val: impl Into<Value>) -> Self {
self.values.push((col.into(), val.into()));
self
}
pub fn operation(mut self, op: Operation) -> Self {
self.operation = op;
self
}
}