use keelson_core::clause::{
HasJoins, HasLimit, HasOrderBy, HasSet, HasWhere, HasWith, Join, Limit, OrderBy, Set, TableRef,
Where, With,
};
use keelson_core::expr::{Expr, IntoExpr, IntoExprList};
use keelson_core::{Dialect, Error, Expression, Mod, Query, QueryExtensions, QueryType, SqlWriter};
use super::{HasExtraTables, HasTargetTable, write_hints_and_modifiers, write_table_list};
use crate::Mysql;
use crate::extras::{HasHints, HasModifiers, Hints, Modifiers};
#[derive(Debug, Clone, Default)]
pub struct UpdateQuery {
pub with: With,
pub hints: Hints,
pub modifiers: Modifiers,
pub table: TableRef,
pub extra_tables: Vec<TableRef>,
pub set: Set,
pub where_: Where,
pub order_by: OrderBy,
pub limit: Limit,
}
impl UpdateQuery {
pub fn new() -> UpdateQuery {
UpdateQuery::default()
}
pub fn apply(&mut self, mods: impl Mod<UpdateQuery>) {
mods.apply(self);
}
}
impl Expression for UpdateQuery {
fn write_sql(&self, w: &mut SqlWriter<'_>) {
w.write_if(!self.with.is_empty(), "", &self.with, " ");
if self.table.is_empty() {
w.record_error(Error::Incomplete("the table of an UPDATE"));
return;
}
if self.set.is_empty() {
w.record_error(Error::Incomplete("the assignments of an UPDATE"));
return;
}
w.push_str("UPDATE ");
write_hints_and_modifiers(w, &self.hints, &self.modifiers);
write_table_list(
w,
"",
&self.table,
&self.extra_tables,
"the table of an UPDATE",
);
w.push_str(" SET ");
w.write_expr(&self.set);
w.write_if(!self.where_.is_empty(), " ", &self.where_, "");
w.write_if(!self.order_by.is_empty(), " ", &self.order_by, "");
w.write_if(!self.limit.is_empty(), " ", &self.limit, "");
}
}
impl Query for UpdateQuery {
fn query_type(&self) -> QueryType {
QueryType::Update
}
fn dialect(&self) -> &dyn Dialect {
&Mysql
}
}
impl<H, L, M> QueryExtensions<H, L, M> for UpdateQuery {}
impl IntoExpr for UpdateQuery {
fn into_expr(self) -> Expr {
crate::query(self)
}
}
impl IntoExprList for UpdateQuery {
fn into_expr_list(self) -> Vec<Expr> {
vec![self.into_expr()]
}
}
impl HasWith for UpdateQuery {
fn with_mut(&mut self) -> &mut With {
&mut self.with
}
}
impl HasHints for UpdateQuery {
fn hints_mut(&mut self) -> &mut Hints {
&mut self.hints
}
}
impl HasModifiers for UpdateQuery {
fn modifiers_mut(&mut self) -> &mut Modifiers {
&mut self.modifiers
}
}
impl HasTargetTable for UpdateQuery {
fn target_table_mut(&mut self) -> &mut TableRef {
&mut self.table
}
}
impl HasExtraTables for UpdateQuery {
fn extra_tables_mut(&mut self) -> &mut Vec<TableRef> {
&mut self.extra_tables
}
}
impl HasJoins for UpdateQuery {
fn joins_mut(&mut self) -> &mut Vec<Join> {
&mut self.table.joins
}
}
impl HasSet for UpdateQuery {
fn set_mut(&mut self) -> &mut Set {
&mut self.set
}
}
impl HasWhere for UpdateQuery {
fn where_mut(&mut self) -> &mut Where {
&mut self.where_
}
}
impl HasOrderBy for UpdateQuery {
fn order_by_mut(&mut self) -> &mut OrderBy {
&mut self.order_by
}
}
impl HasLimit for UpdateQuery {
fn limit_mut(&mut self) -> &mut Limit {
&mut self.limit
}
}