use super::{deserialize::deserialize, schema::Table};
use crate::storage::Error;
use futures_util::TryStreamExt;
use pbbson::Model;
use sqlx::{Pool, Postgres};
pub(super) async fn perform(pool: &Pool<Postgres>, table: &Table, id: &str) -> Result<Model, Error> {
let sql = {
let table_name = &table.name;
let maybe_id_field = table.fields_by_name.get("id");
let param = match maybe_id_field {
None => "$1".to_string(),
Some(field) => format!("$1::{}", field.data_type),
};
format!("SELECT * FROM {table_name} WHERE id = {param}")
};
log::debug!(sql; "Finding one");
let mut rows = sqlx::query(&sql).bind(id).fetch(pool);
let row = match rows.try_next().await.map_err(|e| Error::internal(e.to_string()))? {
None => return Err(Error::not_found("No such record")),
Some(row) => row,
};
let model = deserialize(row, table)?;
Ok(model)
}