use crate::{
backend::QueryBuilder,
prepare::*,
query::{condition::*, OrderedStatement},
types::*,
value::*,
Query, QueryStatementBuilder, QueryStatementWriter, SelectExpr, SelectStatement,
SubQueryStatement, WithClause, WithQuery,
};
#[derive(Debug, Clone)]
pub struct DeleteStatement {
pub(crate) table: Option<Box<TableRef>>,
pub(crate) wherei: ConditionHolder,
pub(crate) orders: Vec<OrderExpr>,
pub(crate) limit: Option<Value>,
pub(crate) returning: Vec<SelectExpr>,
}
impl Default for DeleteStatement {
fn default() -> Self {
Self::new()
}
}
impl DeleteStatement {
pub fn new() -> Self {
Self {
table: None,
wherei: ConditionHolder::new(),
orders: Vec::new(),
limit: None,
returning: Vec::new(),
}
}
#[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 limit(&mut self, limit: u64) -> &mut Self {
self.limit = Some(Value::BigUnsigned(Some(limit)));
self
}
pub fn returning(&mut self, select: SelectStatement) -> &mut Self {
self.returning = select.selects;
self
}
pub fn returning_col<C>(&mut self, col: C) -> &mut Self
where
C: IntoIden,
{
self.returning(Query::select().column(col.into_iden()).take())
}
pub fn with(self, clause: WithClause) -> WithQuery {
clause.query(self)
}
}
impl QueryStatementBuilder for DeleteStatement {
fn build_collect_any_into(
&self,
query_builder: &dyn QueryBuilder,
sql: &mut SqlWriter,
collector: &mut dyn FnMut(Value),
) {
query_builder.prepare_delete_statement(self, sql, collector);
}
fn into_sub_query_statement(self) -> SubQueryStatement {
SubQueryStatement::DeleteStatement(self)
}
}
impl QueryStatementWriter for DeleteStatement {
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()
}
}
impl OrderedStatement for DeleteStatement {
fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
self.orders.push(order);
self
}
}
impl ConditionalStatement for DeleteStatement {
fn and_or_where(&mut self, condition: LogicalChainOper) -> &mut Self {
self.wherei.add_and_or(condition);
self
}
fn cond_where<C>(&mut self, condition: C) -> &mut Self
where
C: IntoCondition,
{
self.wherei.add_condition(condition.into_condition());
self
}
}