use async_trait::async_trait; use libertas_core::{ error::{CoreError, CoreResult}, models::Person, repositories::PersonRepository, }; use sqlx::PgPool; use uuid::Uuid; use crate::db_models::PostgresPerson; #[derive(Clone)] pub struct PostgresPersonRepository { pool: PgPool, } impl PostgresPersonRepository { pub fn new(pool: PgPool) -> Self { Self { pool } } } #[async_trait] impl PersonRepository for PostgresPersonRepository { async fn create(&self, person: Person) -> CoreResult<()> { sqlx::query!( r#" INSERT INTO people (id, owner_id, name) VALUES ($1, $2, $3) "#, person.id, person.owner_id, person.name ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } async fn find_by_id(&self, id: Uuid) -> CoreResult> { let pg_person = sqlx::query_as!( PostgresPerson, r#" SELECT id, owner_id, name FROM people WHERE id = $1 "#, id ) .fetch_optional(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(pg_person.map(Person::from)) } async fn list_by_user(&self, user_id: Uuid) -> CoreResult> { let pg_people = sqlx::query_as!( PostgresPerson, r#" SELECT id, owner_id, name FROM people WHERE owner_id = $1 "#, user_id ) .fetch_all(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(pg_people.into_iter().map(Person::from).collect()) } async fn update(&self, person: Person) -> CoreResult<()> { sqlx::query!( r#" UPDATE people SET name = $1 WHERE id = $2 "#, person.name, person.id ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } async fn delete(&self, id: Uuid) -> CoreResult<()> { sqlx::query!( r#" DELETE FROM people WHERE id = $1 "#, id ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } async fn set_thumbnail_media_id(&self, person_id: Uuid, media_id: Uuid) -> CoreResult<()> { sqlx::query!( r#" UPDATE people SET thumbnail_media_id = $1 WHERE id = $2 "#, media_id, person_id ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } }