use async_trait::async_trait; use libertas_core::{ error::{CoreError, CoreResult}, models::AlbumPermission, repositories::AlbumShareRepository }; use sqlx::PgPool; use uuid::Uuid; use crate::db_models::PostgresAlbumPermission; #[derive(Clone)] pub struct PostgresAlbumShareRepository { pool: PgPool, } impl PostgresAlbumShareRepository { pub fn new(pool: PgPool) -> Self { Self { pool } } } #[async_trait] impl AlbumShareRepository for PostgresAlbumShareRepository { async fn create_or_update_share( &self, album_id: Uuid, user_id: Uuid, permission: AlbumPermission, ) -> CoreResult<()> { sqlx::query!( r#" INSERT INTO album_shares (album_id, user_id, permission) VALUES ($1, $2, $3) ON CONFLICT (album_id, user_id) DO UPDATE SET permission = $3 "#, album_id, user_id, PostgresAlbumPermission::from(permission) as PostgresAlbumPermission, ) .execute(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(()) } async fn get_user_permission( &self, album_id: Uuid, user_id: Uuid, ) -> CoreResult> { let result = sqlx::query!( r#" SELECT permission as "permission: PostgresAlbumPermission" FROM album_shares WHERE album_id = $1 AND user_id = $2 "#, album_id, user_id ) .fetch_optional(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(result.map(|row| row.permission.into())) } async fn is_media_in_shared_album(&self, media_id: Uuid, user_id: Uuid) -> CoreResult { let result = sqlx::query!( r#" SELECT EXISTS ( SELECT 1 FROM album_media am JOIN album_shares ash ON am.album_id = ash.album_id WHERE am.media_id = $1 AND ash.user_id = $2 ) "#, media_id, user_id ) .fetch_one(&self.pool) .await .map_err(|e| CoreError::Database(e.to_string()))?; Ok(result.exists.unwrap_or(false)) } }