feat: implement SqliteProviderConfigRepository, build_provider_config_repository factory

This commit is contained in:
2026-03-16 03:26:02 +01:00
parent 4ca8690a89
commit 0e51b7c0f1
4 changed files with 86 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use crate::db::DatabasePool; use crate::db::DatabasePool;
use domain::{ActivityLogRepository, ChannelRepository, ScheduleRepository, UserRepository}; use domain::{ActivityLogRepository, ChannelRepository, ProviderConfigRepository, ScheduleRepository, UserRepository};
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum FactoryError { pub enum FactoryError {
@@ -70,6 +70,21 @@ pub async fn build_activity_log_repository(
} }
} }
pub async fn build_provider_config_repository(
pool: &DatabasePool,
) -> FactoryResult<Arc<dyn ProviderConfigRepository>> {
match pool {
#[cfg(feature = "sqlite")]
DatabasePool::Sqlite(pool) => Ok(Arc::new(
crate::provider_config_repository::SqliteProviderConfigRepository::new(pool.clone()),
)),
#[allow(unreachable_patterns)]
_ => Err(FactoryError::NotImplemented(
"ProviderConfigRepository not implemented for this database".to_string(),
)),
}
}
pub async fn build_schedule_repository( pub async fn build_schedule_repository(
pool: &DatabasePool, pool: &DatabasePool,
) -> FactoryResult<Arc<dyn ScheduleRepository>> { ) -> FactoryResult<Arc<dyn ScheduleRepository>> {

View File

@@ -20,6 +20,7 @@ pub mod jellyfin;
pub mod provider_registry; pub mod provider_registry;
mod activity_log_repository; mod activity_log_repository;
mod channel_repository; mod channel_repository;
mod provider_config_repository;
mod schedule_repository; mod schedule_repository;
mod user_repository; mod user_repository;
@@ -37,6 +38,8 @@ pub use user_repository::SqliteUserRepository;
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
pub use channel_repository::SqliteChannelRepository; pub use channel_repository::SqliteChannelRepository;
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
pub use provider_config_repository::SqliteProviderConfigRepository;
#[cfg(feature = "sqlite")]
pub use schedule_repository::SqliteScheduleRepository; pub use schedule_repository::SqliteScheduleRepository;
#[cfg(feature = "jellyfin")] #[cfg(feature = "jellyfin")]

View File

@@ -0,0 +1,4 @@
#[cfg(feature = "sqlite")]
mod sqlite;
#[cfg(feature = "sqlite")]
pub use sqlite::SqliteProviderConfigRepository;

View File

@@ -0,0 +1,63 @@
use async_trait::async_trait;
use domain::{DomainError, DomainResult, ProviderConfigRepository, ProviderConfigRow};
#[derive(Clone)]
pub struct SqliteProviderConfigRepository {
pool: sqlx::SqlitePool,
}
impl SqliteProviderConfigRepository {
pub fn new(pool: sqlx::SqlitePool) -> Self {
Self { pool }
}
}
#[async_trait]
impl ProviderConfigRepository for SqliteProviderConfigRepository {
async fn get_all(&self) -> DomainResult<Vec<ProviderConfigRow>> {
let rows: Vec<(String, String, i64, String)> = sqlx::query_as(
"SELECT provider_type, config_json, enabled, updated_at FROM provider_configs",
)
.fetch_all(&self.pool)
.await
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
Ok(rows
.into_iter()
.map(|(provider_type, config_json, enabled, updated_at)| ProviderConfigRow {
provider_type,
config_json,
enabled: enabled != 0,
updated_at,
})
.collect())
}
async fn upsert(&self, row: &ProviderConfigRow) -> DomainResult<()> {
sqlx::query(
r#"INSERT INTO provider_configs (provider_type, config_json, enabled, updated_at)
VALUES (?, ?, ?, ?)
ON CONFLICT(provider_type) DO UPDATE SET
config_json = excluded.config_json,
enabled = excluded.enabled,
updated_at = excluded.updated_at"#,
)
.bind(&row.provider_type)
.bind(&row.config_json)
.bind(row.enabled as i64)
.bind(&row.updated_at)
.execute(&self.pool)
.await
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
Ok(())
}
async fn delete(&self, provider_type: &str) -> DomainResult<()> {
sqlx::query("DELETE FROM provider_configs WHERE provider_type = ?")
.bind(provider_type)
.execute(&self.pool)
.await
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
Ok(())
}
}