1use sqlez_macros::sql;
2
3use crate::{define_connection, query};
4
5define_connection!(pub static ref KEY_VALUE_STORE: KeyValueStore<()> =
6 &[sql!(
7 CREATE TABLE IF NOT EXISTS kv_store(
8 key TEXT PRIMARY KEY,
9 value TEXT NOT NULL
10 ) STRICT;
11 )];
12);
13
14impl KeyValueStore {
15 query! {
16 pub fn read_kvp(key: &str) -> Result<Option<String>> {
17 SELECT value FROM kv_store WHERE key = (?)
18 }
19 }
20
21 pub async fn write_kvp(&self, key: String, value: String) -> anyhow::Result<()> {
22 log::debug!("Writing key-value pair for key {key}");
23 self.write_kvp_inner(key, value).await
24 }
25
26 query! {
27 async fn write_kvp_inner(key: String, value: String) -> Result<()> {
28 INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))
29 }
30 }
31
32 query! {
33 pub async fn delete_kvp(key: String) -> Result<()> {
34 DELETE FROM kv_store WHERE key = (?)
35 }
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use crate::kvp::KeyValueStore;
42
43 #[gpui::test]
44 async fn test_kvp() {
45 let db = KeyValueStore::open_test_db("test_kvp").await;
46
47 assert_eq!(db.read_kvp("key-1").unwrap(), None);
48
49 db.write_kvp("key-1".to_string(), "one".to_string())
50 .await
51 .unwrap();
52 assert_eq!(db.read_kvp("key-1").unwrap(), Some("one".to_string()));
53
54 db.write_kvp("key-1".to_string(), "one-2".to_string())
55 .await
56 .unwrap();
57 assert_eq!(db.read_kvp("key-1").unwrap(), Some("one-2".to_string()));
58
59 db.write_kvp("key-2".to_string(), "two".to_string())
60 .await
61 .unwrap();
62 assert_eq!(db.read_kvp("key-2").unwrap(), Some("two".to_string()));
63
64 db.delete_kvp("key-1".to_string()).await.unwrap();
65 assert_eq!(db.read_kvp("key-1").unwrap(), None);
66 }
67}
68
69define_connection!(pub static ref GLOBAL_KEY_VALUE_STORE: GlobalKeyValueStore<()> =
70 &[sql!(
71 CREATE TABLE IF NOT EXISTS kv_store(
72 key TEXT PRIMARY KEY,
73 value TEXT NOT NULL
74 ) STRICT;
75 )];
76 global
77);
78
79impl GlobalKeyValueStore {
80 query! {
81 pub fn read_kvp(key: &str) -> Result<Option<String>> {
82 SELECT value FROM kv_store WHERE key = (?)
83 }
84 }
85
86 pub async fn write_kvp(&self, key: String, value: String) -> anyhow::Result<()> {
87 log::debug!("Writing global key-value pair for key {key}");
88 self.write_kvp_inner(key, value).await
89 }
90
91 query! {
92 async fn write_kvp_inner(key: String, value: String) -> Result<()> {
93 INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))
94 }
95 }
96
97 query! {
98 pub async fn delete_kvp(key: String) -> Result<()> {
99 DELETE FROM kv_store WHERE key = (?)
100 }
101 }
102}