1use sqlez::domain::Domain;
2use sqlez_macros::sql;
3
4use crate::{connection, query};
5
6connection!(KEY_VALUE_STORE: KeyValueStore<KeyValueStore>);
7
8impl Domain for KeyValueStore {
9 fn name() -> &'static str {
10 "kvp"
11 }
12
13 fn migrations() -> &'static [&'static str] {
14 // Legacy migrations using rusqlite may have already created kv_store during alpha,
15 // migrations must be infallible so this must have 'IF NOT EXISTS'
16 &[sql!(
17 CREATE TABLE IF NOT EXISTS kv_store(
18 key TEXT PRIMARY KEY,
19 value TEXT NOT NULL
20 ) STRICT;
21 )]
22 }
23}
24
25impl KeyValueStore {
26 query! {
27 pub fn read_kvp(key: &str) -> Result<Option<String>> {
28 SELECT value FROM kv_store WHERE key = (?)
29 }
30 }
31
32 query! {
33 pub async fn write_kvp(key: String, value: String) -> Result<()> {
34 INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))
35 }
36 }
37
38 query! {
39 pub async fn delete_kvp(key: String) -> Result<()> {
40 DELETE FROM kv_store WHERE key = (?)
41 }
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use crate::kvp::KeyValueStore;
48
49 #[gpui::test]
50 async fn test_kvp() {
51 let db = KeyValueStore(crate::open_test_db("test_kvp").await);
52
53 assert_eq!(db.read_kvp("key-1").unwrap(), None);
54
55 db.write_kvp("key-1".to_string(), "one".to_string())
56 .await
57 .unwrap();
58 assert_eq!(db.read_kvp("key-1").unwrap(), Some("one".to_string()));
59
60 db.write_kvp("key-1".to_string(), "one-2".to_string())
61 .await
62 .unwrap();
63 assert_eq!(db.read_kvp("key-1").unwrap(), Some("one-2".to_string()));
64
65 db.write_kvp("key-2".to_string(), "two".to_string())
66 .await
67 .unwrap();
68 assert_eq!(db.read_kvp("key-2").unwrap(), Some("two".to_string()));
69
70 db.delete_kvp("key-1".to_string()).await.unwrap();
71 assert_eq!(db.read_kvp("key-1").unwrap(), None);
72 }
73}