kvp.rs

 1use anyhow::Result;
 2use rusqlite::OptionalExtension;
 3
 4use super::Db;
 5
 6pub(crate) const KVP_M_1_UP: &str = "
 7CREATE TABLE kv_store(
 8    key TEXT PRIMARY KEY,
 9    value TEXT NOT NULL
10) STRICT;
11";
12
13impl Db {
14    pub fn read_kvp(&self, key: &str) -> Result<Option<String>> {
15        self.real()
16            .map(|db| {
17                let lock = db.connection.lock();
18                let mut stmt = lock.prepare_cached("SELECT value FROM kv_store WHERE key = (?)")?;
19
20                Ok(stmt.query_row([key], |row| row.get(0)).optional()?)
21            })
22            .unwrap_or(Ok(None))
23    }
24
25    pub fn write_kvp(&self, key: &str, value: &str) -> Result<()> {
26        self.real()
27            .map(|db| {
28                let lock = db.connection.lock();
29
30                let mut stmt = lock.prepare_cached(
31                    "INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))",
32                )?;
33
34                stmt.execute([key, value])?;
35
36                Ok(())
37            })
38            .unwrap_or(Ok(()))
39    }
40
41    pub fn delete_kvp(&self, key: &str) -> Result<()> {
42        self.real()
43            .map(|db| {
44                let lock = db.connection.lock();
45
46                let mut stmt = lock.prepare_cached("DELETE FROM kv_store WHERE key = (?)")?;
47
48                stmt.execute([key])?;
49
50                Ok(())
51            })
52            .unwrap_or(Ok(()))
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use anyhow::Result;
59
60    use super::*;
61
62    #[test]
63    fn test_kvp() -> Result<()> {
64        let db = Db::open_in_memory();
65
66        assert_eq!(db.read_kvp("key-1")?, None);
67
68        db.write_kvp("key-1", "one")?;
69        assert_eq!(db.read_kvp("key-1")?, Some("one".to_string()));
70
71        db.write_kvp("key-1", "one-2")?;
72        assert_eq!(db.read_kvp("key-1")?, Some("one-2".to_string()));
73
74        db.write_kvp("key-2", "two")?;
75        assert_eq!(db.read_kvp("key-2")?, Some("two".to_string()));
76
77        db.delete_kvp("key-1")?;
78        assert_eq!(db.read_kvp("key-1")?, None);
79
80        Ok(())
81    }
82}