use crate::model::Model;
use crate::Database;
use craken_http::error::CrakenError;
use sqlx::{query_as, Postgres};
use std::sync::Arc;
pub struct Repository<T: Model> {
db: Arc<Database>,
_phantom: std::marker::PhantomData<T>,
}
impl<T: Model> Repository<T> {
pub fn new(db: Arc<Database>) -> Self {
Self {
db,
_phantom: std::marker::PhantomData,
}
}
pub async fn find(&self, id: i64) -> Result<T, CrakenError> {
let sql = format!(
"SELECT * FROM {} WHERE {} = $1",
T::table_name(),
T::primary_key()
);
query_as::<Postgres, T>(&sql)
.bind(id)
.fetch_one(self.db.pool())
.await
.map_err(Database::map_error)
}
pub async fn all(&self) -> Result<Vec<T>, CrakenError> {
let sql = format!("SELECT * FROM {}", T::table_name());
query_as::<Postgres, T>(&sql)
.fetch_all(self.db.pool())
.await
.map_err(Database::map_error)
}
pub async fn delete(&self, id: i64) -> Result<u64, CrakenError> {
let sql = format!(
"DELETE FROM {} WHERE {} = $1",
T::table_name(),
T::primary_key()
);
sqlx::query(&sql)
.bind(id)
.execute(self.db.pool())
.await
.map(|res| res.rows_affected())
.map_err(Database::map_error)
}
}