84 lines
2.7 KiB
Rust
84 lines
2.7 KiB
Rust
//! 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"));
|
|
}
|
|
}
|