store_sqlite/
config_store.rs1use std::sync::Mutex;
4
5use chrono::Utc;
6use rusqlite::{params, Connection};
7use serde::Serialize;
8
9use crate::error::StoreError;
10use crate::schema;
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
14pub struct ConfigEntry {
15 pub key: String,
17 pub value: String,
19}
20
21pub struct SqliteConfigStore {
23 conn: Mutex<Connection>,
24}
25
26impl SqliteConfigStore {
27 pub fn open(path: &str) -> Result<Self, StoreError> {
29 let conn = Connection::open(path)?;
30 schema::init(&conn)?;
31 Ok(Self {
32 conn: Mutex::new(conn),
33 })
34 }
35
36 pub fn open_in_memory() -> Result<Self, StoreError> {
38 let conn = Connection::open_in_memory()?;
39 schema::init(&conn)?;
40 Ok(Self {
41 conn: Mutex::new(conn),
42 })
43 }
44
45 pub fn set(&self, key: &str, value: &str) -> Result<ConfigEntry, StoreError> {
47 let updated_at = Utc::now().to_rfc3339();
48 let conn = self.conn.lock().unwrap();
49 conn.execute(
50 "INSERT INTO gateway_config (key, value, updated_at) VALUES (?1, ?2, ?3)
51 ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at",
52 params![key, value, updated_at],
53 )?;
54 Ok(ConfigEntry {
55 key: key.to_string(),
56 value: value.to_string(),
57 })
58 }
59
60 pub fn get(&self, key: &str) -> Result<Option<ConfigEntry>, StoreError> {
62 let conn = self.conn.lock().unwrap();
63 let mut stmt = conn.prepare("SELECT key, value FROM gateway_config WHERE key = ?1")?;
64 let mut rows = stmt.query(params![key])?;
65 if let Some(row) = rows.next()? {
66 Ok(Some(ConfigEntry {
67 key: row.get(0)?,
68 value: row.get(1)?,
69 }))
70 } else {
71 Ok(None)
72 }
73 }
74
75 pub fn delete(&self, key: &str) -> Result<bool, StoreError> {
77 let conn = self.conn.lock().unwrap();
78 let n = conn.execute("DELETE FROM gateway_config WHERE key = ?1", params![key])?;
79 Ok(n > 0)
80 }
81
82 pub fn list(&self) -> Result<Vec<ConfigEntry>, StoreError> {
84 let conn = self.conn.lock().unwrap();
85 let mut stmt = conn.prepare("SELECT key, value FROM gateway_config ORDER BY key")?;
86 let rows = stmt.query_map([], |row| {
87 Ok(ConfigEntry {
88 key: row.get(0)?,
89 value: row.get(1)?,
90 })
91 })?;
92 rows.collect::<Result<Vec<_>, _>>()
93 .map_err(StoreError::from)
94 }
95}