feat(infra): add SqliteAppSettingsRepository
This commit is contained in:
83
k-tv-backend/infra/src/app_settings_repository.rs
Normal file
83
k-tv-backend/infra/src/app_settings_repository.rs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
//! SQLite implementation of IAppSettingsRepository.
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
|
use domain::{DomainError, DomainResult, IAppSettingsRepository};
|
||||||
|
|
||||||
|
pub struct SqliteAppSettingsRepository {
|
||||||
|
pool: SqlitePool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqliteAppSettingsRepository {
|
||||||
|
pub fn new(pool: SqlitePool) -> Self {
|
||||||
|
Self { pool }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl IAppSettingsRepository for SqliteAppSettingsRepository {
|
||||||
|
async fn get(&self, key: &str) -> DomainResult<Option<String>> {
|
||||||
|
sqlx::query_scalar::<_, String>("SELECT value FROM app_settings WHERE key = ?")
|
||||||
|
.bind(key)
|
||||||
|
.fetch_optional(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| DomainError::InfrastructureError(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set(&self, key: &str, value: &str) -> DomainResult<()> {
|
||||||
|
sqlx::query("INSERT OR REPLACE INTO app_settings (key, value) VALUES (?, ?)")
|
||||||
|
.bind(key)
|
||||||
|
.bind(value)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(|e| DomainError::InfrastructureError(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_all(&self) -> DomainResult<Vec<(String, String)>> {
|
||||||
|
sqlx::query_as::<_, (String, String)>("SELECT key, value FROM app_settings ORDER BY key")
|
||||||
|
.fetch_all(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| DomainError::InfrastructureError(e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
|
use domain::IAppSettingsRepository;
|
||||||
|
|
||||||
|
async fn setup() -> SqlitePool {
|
||||||
|
let pool = SqlitePool::connect(":memory:").await.unwrap();
|
||||||
|
sqlx::query(
|
||||||
|
"CREATE TABLE app_settings (key TEXT PRIMARY KEY, value TEXT NOT NULL)"
|
||||||
|
).execute(&pool).await.unwrap();
|
||||||
|
sqlx::query("INSERT INTO app_settings VALUES ('library_sync_interval_hours', '6')")
|
||||||
|
.execute(&pool).await.unwrap();
|
||||||
|
pool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_returns_seeded_value() {
|
||||||
|
let repo = SqliteAppSettingsRepository::new(setup().await);
|
||||||
|
let val = repo.get("library_sync_interval_hours").await.unwrap();
|
||||||
|
assert_eq!(val, Some("6".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn set_then_get() {
|
||||||
|
let repo = SqliteAppSettingsRepository::new(setup().await);
|
||||||
|
repo.set("library_sync_interval_hours", "12").await.unwrap();
|
||||||
|
let val = repo.get("library_sync_interval_hours").await.unwrap();
|
||||||
|
assert_eq!(val, Some("12".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_all_returns_all_keys() {
|
||||||
|
let repo = SqliteAppSettingsRepository::new(setup().await);
|
||||||
|
let all = repo.get_all().await.unwrap();
|
||||||
|
assert!(!all.is_empty());
|
||||||
|
assert!(all.iter().any(|(k, _)| k == "library_sync_interval_hours"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ pub mod db;
|
|||||||
pub mod factory;
|
pub mod factory;
|
||||||
pub mod jellyfin;
|
pub mod jellyfin;
|
||||||
pub mod provider_registry;
|
pub mod provider_registry;
|
||||||
|
mod app_settings_repository;
|
||||||
mod activity_log_repository;
|
mod activity_log_repository;
|
||||||
mod channel_repository;
|
mod channel_repository;
|
||||||
mod library_repository;
|
mod library_repository;
|
||||||
@@ -33,6 +34,8 @@ pub mod local_files;
|
|||||||
pub use db::run_migrations;
|
pub use db::run_migrations;
|
||||||
pub use provider_registry::ProviderRegistry;
|
pub use provider_registry::ProviderRegistry;
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
pub use app_settings_repository::SqliteAppSettingsRepository;
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
pub use activity_log_repository::SqliteActivityLogRepository;
|
pub use activity_log_repository::SqliteActivityLogRepository;
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
|
|||||||
Reference in New Issue
Block a user