use sqlx::SqlitePool;
pub const RECORDING_MAX_BYTES: &str = "recording_max_bytes";
pub const RECORDING_MIN_FREE_BYTES: &str = "recording_min_free_bytes";
pub async fn get_i64(pool: &SqlitePool, key: &str) -> Option<i64> {
let raw: Option<String> = sqlx::query_scalar("SELECT value FROM settings WHERE key = ?")
.bind(key)
.fetch_optional(pool)
.await
.ok()
.flatten();
raw.and_then(|s| s.parse::<i64>().ok())
}
pub async fn set_i64(pool: &SqlitePool, key: &str, value: i64) -> sqlx::Result<()> {
sqlx::query(
"INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at",
)
.bind(key)
.bind(value.to_string())
.bind(chrono::Utc::now().to_rfc3339())
.execute(pool)
.await?;
Ok(())
}
pub async fn clear(pool: &SqlitePool, key: &str) -> sqlx::Result<()> {
sqlx::query("DELETE FROM settings WHERE key = ?")
.bind(key)
.execute(pool)
.await?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
async fn mem_pool() -> SqlitePool {
let pool = sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(1)
.connect("sqlite::memory:")
.await
.unwrap();
crate::db::run_migrations(&pool).await.unwrap();
pool
}
#[tokio::test]
async fn set_get_clear_roundtrip() {
let pool = mem_pool().await;
assert_eq!(get_i64(&pool, RECORDING_MAX_BYTES).await, None);
set_i64(&pool, RECORDING_MAX_BYTES, 500_000_000)
.await
.unwrap();
assert_eq!(get_i64(&pool, RECORDING_MAX_BYTES).await, Some(500_000_000));
set_i64(&pool, RECORDING_MAX_BYTES, 1_000_000_000)
.await
.unwrap();
assert_eq!(
get_i64(&pool, RECORDING_MAX_BYTES).await,
Some(1_000_000_000)
);
clear(&pool, RECORDING_MAX_BYTES).await.unwrap();
assert_eq!(get_i64(&pool, RECORDING_MAX_BYTES).await, None);
}
}