use crate::{backend::QueryBuilder, types::*, expr::*, value::*, prepare::*};
#[derive(Debug, Clone)]
pub struct DeleteStatement {
pub(crate) table: Option<Box<TableRef>>,
pub(crate) wherei: Option<Box<SimpleExpr>>,
pub(crate) orders: Vec<OrderExpr>,
pub(crate) limit: Option<Value>,
}
impl Default for DeleteStatement {
fn default() -> Self {
Self::new()
}
}
impl DeleteStatement {
pub fn new() -> Self {
Self {
table: None,
wherei: None,
orders: Vec::new(),
limit: None,
}
}
#[allow(clippy::wrong_self_convention)]
pub fn from_table<T>(&mut self, tbl_ref: T) -> &mut Self
where T: IntoTableRef {
self.table = Some(Box::new(tbl_ref.into_table_ref()));
self
}
pub fn and_where(&mut self, other: SimpleExpr) -> &mut Self {
self.and_or_where(BinOper::And, other)
}
pub fn or_where(&mut self, other: SimpleExpr) -> &mut Self {
self.and_or_where(BinOper::Or, other)
}
fn and_or_where(&mut self, bopr: BinOper, right: SimpleExpr) -> &mut Self {
self.wherei = Self::merge_expr(
self.wherei.take(),
match bopr {
BinOper::And => BinOper::And,
BinOper::Or => BinOper::Or,
_ => panic!("not allow"),
},
right
);
self
}
fn merge_expr(left: Option<Box<SimpleExpr>>, bopr: BinOper, right: SimpleExpr) -> Option<Box<SimpleExpr>> {
Some(Box::new(match left {
Some(left) => SimpleExpr::Binary(
left,
bopr,
Box::new(right)
),
None => right,
}))
}
pub fn order_by<T>(&mut self, col: T, order: Order) -> &mut Self
where T: IntoColumnRef {
self.orders.push(OrderExpr {
expr: SimpleExpr::Column(col.into_column_ref()),
order,
});
self
}
#[deprecated(
since = "0.9.0",
note = "Please use the [`DeleteStatement::order_by`] with a tuple as [`ColumnRef`]"
)]
pub fn order_by_tbl<T, C>
(&mut self, table: T, col: C, order: Order) -> &mut Self
where T: IntoIden, C: IntoIden {
self.order_by((table.into_iden(), col.into_iden()), order)
}
pub fn order_by_expr(&mut self, expr: SimpleExpr, order: Order) -> &mut Self {
self.orders.push(OrderExpr {
expr,
order,
});
self
}
pub fn order_by_customs<T>(&mut self, cols: Vec<(T, Order)>) -> &mut Self
where T: ToString {
let mut orders = cols.into_iter().map(
|(c, order)| OrderExpr {
expr: SimpleExpr::Custom(c.to_string()),
order,
}).collect();
self.orders.append(&mut orders);
self
}
pub fn order_by_columns<T>(&mut self, cols: Vec<(T, Order)>) -> &mut Self
where T: IntoColumnRef {
let mut orders = cols.into_iter().map(
|(c, order)| OrderExpr {
expr: SimpleExpr::Column(c.into_column_ref()),
order,
}).collect();
self.orders.append(&mut orders);
self
}
#[deprecated(
since = "0.9.0",
note = "Please use the [`DeleteStatement::order_by_columns`] with a tuple as [`ColumnRef`]"
)]
pub fn order_by_table_columns<T, C>
(&mut self, cols: Vec<(T, C, Order)>) -> &mut Self
where T: IntoIden, C: IntoIden {
self.order_by_columns(cols.into_iter().map(|(t, c, o)| ((t.into_iden(), c.into_iden()), o)).collect())
}
pub fn limit(&mut self, limit: u64) -> &mut Self {
self.limit = Some(Value::BigUnsigned(limit));
self
}
pub fn build_collect<T: QueryBuilder>(&self, query_builder: T, collector: &mut dyn FnMut(Value)) -> String {
let mut sql = SqlWriter::new();
query_builder.prepare_delete_statement(self, &mut sql, collector);
sql.result()
}
pub fn build_collect_any(&self, query_builder: &dyn QueryBuilder, collector: &mut dyn FnMut(Value)) -> String {
let mut sql = SqlWriter::new();
query_builder.prepare_delete_statement(self, &mut sql, collector);
sql.result()
}
pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values) {
let mut values = Vec::new();
let mut collector = |v| values.push(v);
let sql = self.build_collect(query_builder, &mut collector);
(sql, Values(values))
}
pub fn build_any(&self, query_builder: &dyn QueryBuilder) -> (String, Values) {
let mut values = Vec::new();
let mut collector = |v| values.push(v);
let sql = self.build_collect_any(query_builder, &mut collector);
(sql, Values(values))
}
pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String {
let (sql, values) = self.build_any(&query_builder);
inject_parameters(&sql, values.0, &query_builder)
}
}