use super::{
create::{bind, find_field},
schema::Table,
};
use crate::storage::Error;
use pbbson::Model;
use sqlx::{Execute, Pool, Postgres, QueryBuilder};
pub(super) async fn perform(pool: &Pool<Postgres>, table: &Table, model: Model) -> Result<(), Error> {
let mut qb: QueryBuilder<Postgres> = QueryBuilder::new("UPDATE ");
qb.push(&table.name);
qb.push(" SET ");
let mut field_num = 0;
for (k, v) in model.iter() {
let field = match find_field(table, k) {
Some(field) => field,
None => {
log::error!(field = k; "No db column found for field");
continue;
}
};
if table.primary_key.contains(&field.column_name) {
continue;
}
field_num += 1;
if field_num > 1 {
qb.push(", ");
}
qb.push(&field.column_name);
qb.push("=");
bind(&field, v, &mut qb)?;
}
qb.push(" WHERE id = ");
qb.push_bind(model.id()?);
if let Some(field) = find_field(table, "id") {
qb.push("::");
qb.push(field.data_type.clone());
}
let query = qb.build();
let sql = query.sql();
log::debug!(sql; "Updating");
let res = query.execute(pool).await?;
if res.rows_affected() == 0 {
return Err(Error::NotFound("No such record".to_string()));
}
Ok(())
}