Skip to main content

max / balanced_breakfast

1.4 KB · 52 lines History Blame Raw
1 use super::SqlitePool;
2
3 #[derive(Clone)]
4 /// Repository for user_config key-value pairs (theme, welcome flag, etc.)
5 pub struct ConfigRepository {
6 pool: SqlitePool,
7 }
8
9 impl ConfigRepository {
10 #[tracing::instrument(skip_all)]
11 pub fn new(pool: SqlitePool) -> Self {
12 Self { pool }
13 }
14
15 /// Get a config value by key.
16 #[tracing::instrument(skip_all)]
17 pub async fn get(&self, key: &str) -> Result<Option<String>, sqlx::Error> {
18 let row: Option<(String,)> = sqlx::query_as("SELECT value FROM user_config WHERE key = ?1")
19 .bind(key)
20 .fetch_optional(&self.pool)
21 .await?;
22 Ok(row.map(|(v,)| v))
23 }
24
25 /// Set a config value, inserting or updating on conflict.
26 #[tracing::instrument(skip_all)]
27 pub async fn set(&self, key: &str, value: &str) -> Result<(), sqlx::Error> {
28 sqlx::query(
29 r"
30 INSERT INTO user_config (key, value)
31 VALUES (?1, ?2)
32 ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
33 ",
34 )
35 .bind(key)
36 .bind(value)
37 .execute(&self.pool)
38 .await?;
39 Ok(())
40 }
41
42 /// Delete a config entry by key.
43 #[tracing::instrument(skip_all)]
44 pub async fn delete(&self, key: &str) -> Result<(), sqlx::Error> {
45 sqlx::query("DELETE FROM user_config WHERE key = ?1")
46 .bind(key)
47 .execute(&self.pool)
48 .await?;
49 Ok(())
50 }
51 }
52