use super::SqlitePool; #[derive(Clone)] /// Repository for user_config key-value pairs (theme, welcome flag, etc.) pub struct ConfigRepository { pool: SqlitePool, } impl ConfigRepository { #[tracing::instrument(skip_all)] pub fn new(pool: SqlitePool) -> Self { Self { pool } } /// Get a config value by key. #[tracing::instrument(skip_all)] pub async fn get(&self, key: &str) -> Result, sqlx::Error> { let row: Option<(String,)> = sqlx::query_as("SELECT value FROM user_config WHERE key = ?1") .bind(key) .fetch_optional(&self.pool) .await?; Ok(row.map(|(v,)| v)) } /// Set a config value, inserting or updating on conflict. #[tracing::instrument(skip_all)] pub async fn set(&self, key: &str, value: &str) -> Result<(), sqlx::Error> { sqlx::query( r" INSERT INTO user_config (key, value) VALUES (?1, ?2) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value ", ) .bind(key) .bind(value) .execute(&self.pool) .await?; Ok(()) } /// Delete a config entry by key. #[tracing::instrument(skip_all)] pub async fn delete(&self, key: &str) -> Result<(), sqlx::Error> { sqlx::query("DELETE FROM user_config WHERE key = ?1") .bind(key) .execute(&self.pool) .await?; Ok(()) } }