use crate::{Columns, Parameterized, PgParams, Sql, Term};
#[derive(Clone)]
pub struct Update<'a> {
pub table: &'a str,
pub columns: Vec<&'a str>,
pub values: Vec<&'a str>,
pub from: Option<&'a str>,
pub where_clause: Option<Term<'a>>,
pub returning: Option<Columns<'a>>,
}
impl<'a> Sql for Update<'a> {
fn sql(&self) -> String {
let mut result = format!("UPDATE {} SET ", self.table);
let mut first = true;
for (c, v) in self.columns.iter().zip(self.values.iter()) {
if !first {
result.push_str(", ");
}
first = false;
result.push_str(&format!("{} = {}", c, v));
}
if let Some(from) = &self.from {
result.push_str(&format!(" FROM {}", from));
}
if let Some(conditions) = &self.where_clause {
result.push_str(&format!(" WHERE {}", conditions.sql()));
}
if let Some(returning) = &self.returning {
result.push_str(&format!(" RETURNING {}", returning.sql()));
}
result
}
}
pub struct UpdateBuilder<'a> {
table: &'a str,
columns: Vec<&'a str>,
values: Vec<&'a str>,
from: Option<&'a str>,
where_clause: Option<Term<'a>>,
returning: Option<Columns<'a>>,
params: PgParams,
}
#[allow(non_snake_case)]
pub fn U<'a>(table: &'a str) -> UpdateBuilder<'a> {
UpdateBuilder {
table,
columns: Vec::new(),
values: Vec::new(),
from: None,
where_clause: None,
returning: None,
params: PgParams::new(),
}
}
impl<'a> UpdateBuilder<'a> {
pub fn set(&'a mut self, pairs: Vec<(&'a str, &'a str)>) -> &'a mut UpdateBuilder<'a> {
for (col, val) in pairs {
self.columns.push(col);
self.values.push(val);
}
self
}
pub fn columns(&'a mut self, columns: Vec<&'a str>) -> &'a mut UpdateBuilder<'a> {
for c in columns {
self.columns.push(c);
}
self
}
pub fn values(&'a mut self, values: Vec<&'a str>) -> &'a mut UpdateBuilder<'a> {
for v in values {
self.values.push(v);
}
self
}
pub fn from(&'a mut self, from: &'a str) -> &'a mut UpdateBuilder<'a> {
self.from = Some(from);
self
}
pub fn where_(&'a mut self, term: Term<'a>) -> &'a mut UpdateBuilder<'a> {
self.where_clause = Some(term);
self
}
pub fn returning(&'a mut self, columns: Columns<'a>) -> &'a mut UpdateBuilder<'a> {
self.returning = Some(columns);
self
}
pub fn build(&self) -> Update<'a> {
Update {
table: self.table,
columns: self.columns.clone(),
values: self.values.clone(),
from: self.from,
where_clause: self.where_clause.clone(),
returning: self.returning.clone(),
}
}
}
impl<'a> Parameterized for UpdateBuilder<'a> {
fn param(&mut self) -> String {
self.params.seq()
}
}