use crate::{
backend::QueryBuilder,
expr::*,
prepare::*,
query::{condition::*, OrderedStatement},
types::*,
value::*,
QueryStatementBuilder,
};
#[cfg(feature = "with-json")]
use serde_json::Value as JsonValue;
#[derive(Debug, Clone)]
pub struct UpdateStatement {
pub(crate) table: Option<Box<TableRef>>,
pub(crate) values: Vec<(String, Box<SimpleExpr>)>,
pub(crate) wherei: ConditionHolder,
pub(crate) orders: Vec<OrderExpr>,
pub(crate) limit: Option<Value>,
}
impl Default for UpdateStatement {
fn default() -> Self {
Self::new()
}
}
impl UpdateStatement {
pub fn new() -> Self {
Self {
table: None,
values: Vec::new(),
wherei: ConditionHolder::new(),
orders: Vec::new(),
limit: None,
}
}
#[allow(clippy::wrong_self_convention)]
pub fn table<T>(&mut self, tbl_ref: T) -> &mut Self
where
T: IntoTableRef,
{
self.table = Some(Box::new(tbl_ref.into_table_ref()));
self
}
#[deprecated(
since = "0.5.0",
note = "Please use the UpdateStatement::table function instead"
)]
#[allow(clippy::wrong_self_convention)]
pub fn into_table<T>(&mut self, table: T) -> &mut Self
where
T: IntoTableRef,
{
self.table(table)
}
pub fn value_expr<T>(&mut self, col: T, exp: SimpleExpr) -> &mut Self
where
T: IntoIden,
{
self.push_boxed_value(col.into_iden().to_string(), exp);
self
}
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
pub fn json(&mut self, values: JsonValue) -> &mut Self {
match values {
JsonValue::Object(_) => (),
_ => unimplemented!(),
}
for (k, v) in values.as_object().unwrap() {
let v = json_value_to_sea_value(v);
self.push_boxed_value(k.into(), SimpleExpr::Value(v));
}
self
}
pub fn values<T, I>(&mut self, values: I) -> &mut Self
where
T: IntoIden,
I: IntoIterator<Item = (T, Value)>,
{
for (k, v) in values.into_iter() {
self.push_boxed_value(k.into_iden().to_string(), SimpleExpr::Value(v));
}
self
}
pub fn value<T>(&mut self, col: T, value: Value) -> &mut Self
where
T: IntoIden,
{
self.push_boxed_value(col.into_iden().to_string(), SimpleExpr::Value(value));
self
}
fn push_boxed_value(&mut self, k: String, v: SimpleExpr) -> &mut Self {
self.values.push((k, Box::new(v)));
self
}
pub fn limit(&mut self, limit: u64) -> &mut Self {
self.limit = Some(Value::BigUnsigned(limit));
self
}
}
impl QueryStatementBuilder for UpdateStatement {
fn build_collect<T: QueryBuilder>(
&self,
query_builder: T,
collector: &mut dyn FnMut(Value),
) -> String {
let mut sql = SqlWriter::new();
query_builder.prepare_update_statement(self, &mut sql, collector);
sql.result()
}
fn build_collect_any(
&self,
query_builder: &dyn QueryBuilder,
collector: &mut dyn FnMut(Value),
) -> String {
let mut sql = SqlWriter::new();
query_builder.prepare_update_statement(self, &mut sql, collector);
sql.result()
}
}
impl OrderedStatement for UpdateStatement {
fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
self.orders.push(order);
self
}
}
impl ConditionalStatement for UpdateStatement {
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
}
}