heldar_kernel/services/
settings.rs1use sqlx::SqlitePool;
7
8pub const RECORDING_MAX_BYTES: &str = "recording_max_bytes";
10pub const RECORDING_MIN_FREE_BYTES: &str = "recording_min_free_bytes";
12
13pub async fn get_i64(pool: &SqlitePool, key: &str) -> Option<i64> {
15 let raw: Option<String> = sqlx::query_scalar("SELECT value FROM settings WHERE key = ?")
16 .bind(key)
17 .fetch_optional(pool)
18 .await
19 .ok()
20 .flatten();
21 raw.and_then(|s| s.parse::<i64>().ok())
22}
23
24pub async fn set_i64(pool: &SqlitePool, key: &str, value: i64) -> sqlx::Result<()> {
26 sqlx::query(
27 "INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)
28 ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at",
29 )
30 .bind(key)
31 .bind(value.to_string())
32 .bind(chrono::Utc::now().to_rfc3339())
33 .execute(pool)
34 .await?;
35 Ok(())
36}
37
38pub async fn clear(pool: &SqlitePool, key: &str) -> sqlx::Result<()> {
40 sqlx::query("DELETE FROM settings WHERE key = ?")
41 .bind(key)
42 .execute(pool)
43 .await?;
44 Ok(())
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 async fn mem_pool() -> SqlitePool {
52 let pool = sqlx::sqlite::SqlitePoolOptions::new()
53 .max_connections(1)
54 .connect("sqlite::memory:")
55 .await
56 .unwrap();
57 crate::db::run_migrations(&pool).await.unwrap();
58 pool
59 }
60
61 #[tokio::test]
62 async fn set_get_clear_roundtrip() {
63 let pool = mem_pool().await;
64 assert_eq!(get_i64(&pool, RECORDING_MAX_BYTES).await, None);
66 set_i64(&pool, RECORDING_MAX_BYTES, 500_000_000)
68 .await
69 .unwrap();
70 assert_eq!(get_i64(&pool, RECORDING_MAX_BYTES).await, Some(500_000_000));
71 set_i64(&pool, RECORDING_MAX_BYTES, 1_000_000_000)
73 .await
74 .unwrap();
75 assert_eq!(
76 get_i64(&pool, RECORDING_MAX_BYTES).await,
77 Some(1_000_000_000)
78 );
79 clear(&pool, RECORDING_MAX_BYTES).await.unwrap();
81 assert_eq!(get_i64(&pool, RECORDING_MAX_BYTES).await, None);
82 }
83}