use super::super::{
builder::QueryBuilder,
clause::{ClauseAdder, wherein::WhereIn},
helpers::{build_where, join_sql_parts},
};
use crate::Syntax;
use crate::errors::Result;
use crate::model_traits::UniqueIdentifier;
use crate::model_traits::{HasSchema, TableColumns, TableInfo};
use crate::query::clause::ParamArgs;
use crate::writers::NextParam;
use crate::writers::TableWriter;
use welds_connections::Client;
impl<T> QueryBuilder<T>
where
T: Send + Unpin + HasSchema,
{
pub fn delete_sql(&self, syntax: Syntax) -> String
where
<T as HasSchema>::Schema: TableInfo + TableColumns + UniqueIdentifier,
{
let mut w_in = WhereIn::new(self);
self.delete_sql_internal(syntax, &mut w_in, &mut None)
}
fn delete_sql_internal<'s, 'w, 'args, 'p>(
&'s self,
syntax: Syntax,
w_in: &'w mut WhereIn<T>,
args: &'args mut Option<ParamArgs<'p>>,
) -> String
where
'w: 'p,
's: 'p,
<T as HasSchema>::Schema: UniqueIdentifier + TableInfo + TableColumns,
{
let next_params = NextParam::new(syntax);
let parts = <T as HasSchema>::Schema::identifier();
let alias = TableWriter::new(syntax).write2(parts);
join_sql_parts(&[
build_head_delete::<<T as HasSchema>::Schema>(syntax),
build_where_delete(syntax, &next_params, &alias, args, self, w_in),
])
}
#[maybe_async::maybe_async]
pub async fn delete(&self, client: &dyn Client) -> Result<u64>
where
<T as HasSchema>::Schema: UniqueIdentifier + TableInfo + TableColumns,
{
let w_in_q = self;
let mut w_in = WhereIn::new(w_in_q);
let syntax = client.syntax();
let mut args: Option<ParamArgs> = Some(Vec::default());
let sql = self.delete_sql_internal(syntax, &mut w_in, &mut args);
let args: ParamArgs = args.unwrap();
let results = client.execute(&sql, &args).await?;
Ok(results.rows_affected())
}
}
fn build_head_delete<S>(syntax: Syntax) -> Option<String>
where
S: TableInfo + TableColumns,
{
let parts = S::identifier();
let identifier = TableWriter::new(syntax).write2(parts);
Some(format!("DELETE FROM {}", identifier))
}
fn build_where_delete<'args, 'p, 'qb, 'w, T>(
syntax: Syntax,
next_params: &NextParam,
alias: &str,
args: &'args mut Option<ParamArgs<'p>>,
qb: &'qb QueryBuilder<T>,
w_in: &'w mut WhereIn<T>,
) -> Option<String>
where
'qb: 'p,
'w: 'p,
T: HasSchema,
<T as HasSchema>::Schema: UniqueIdentifier + TableInfo + TableColumns,
{
if qb.limit.is_none() {
let wheres = qb.wheres.as_slice();
let exists_in = qb.exist_ins.as_slice();
return build_where(syntax, next_params, alias, wheres, args, exists_in);
}
let mut where_sql: Vec<String> = Vec::default();
if let Some(args) = args {
w_in.bind(args);
}
if let Some(p) = w_in.clause(syntax, alias, next_params) {
where_sql.push(p);
}
if where_sql.is_empty() {
return None;
}
Some(format!("WHERE ( {} )", where_sql.join(" AND ")))
}