use async_trait::async_trait; use libertas_core::{ error::{CoreError, CoreResult}, models::Media, repositories::MediaRepository, }; use sqlx::PgPool; use uuid::Uuid; use crate::db_models::PostgresMedia; #[derive(Clone)] pub struct PostgresMediaRepository { pool: PgPool, } impl PostgresMediaRepository { pub fn new(pool: PgPool) -> Self { Self { pool } } } #[async_trait] impl MediaRepository for PostgresMediaRepository { async fn create(&self, media: &Media) -> CoreResult<()> { sqlx::query!( r#" INSERT INTO media (id, owner_id, storage_path, original_filename, mime_type, hash, created_at, width, height) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) "#, media.id, media.owner_id, media.storage_path, media.original_filename, media.mime_type, media.hash, media.created_at, media.width, media.height ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } async fn find_by_hash(&self, hash: &str) -> CoreResult> { let pg_media = sqlx::query_as!( PostgresMedia, r#" SELECT id, owner_id, storage_path, original_filename, mime_type, hash, created_at, extracted_location, width, height FROM media WHERE hash = $1 "#, hash ) .fetch_optional(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(pg_media.map(|m| m.into())) } async fn find_by_id(&self, id: Uuid) -> CoreResult> { let pg_media = sqlx::query_as!( PostgresMedia, r#" SELECT id, owner_id, storage_path, original_filename, mime_type, hash, created_at, extracted_location, width, height FROM media WHERE id = $1 "#, id ) .fetch_optional(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(pg_media.map(|m| m.into())) } async fn list_by_user(&self, user_id: Uuid) -> CoreResult> { let pg_media = sqlx::query_as!( PostgresMedia, r#" SELECT id, owner_id, storage_path, original_filename, mime_type, hash, created_at, extracted_location, width, height FROM media WHERE owner_id = $1 "#, user_id ) .fetch_all(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(pg_media.into_iter().map(|m| m.into()).collect()) } async fn update_metadata( &self, id: Uuid, width: Option, height: Option, location: Option, ) -> CoreResult<()> { sqlx::query!( r#" UPDATE media SET width = $2, height = $3, extracted_location = $4 WHERE id = $1 "#, id, width, height, location ) .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 media WHERE id = $1 "#, id ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } }