1use sqlez::{domain::Domain, thread_safe_connection::ThreadSafeConnection};
2use sqlez_macros::sql;
3
4use crate::{open_file_db, open_memory_db, query};
5
6pub struct KeyValueStore(ThreadSafeConnection<KeyValueStore>);
7
8impl std::ops::Deref for KeyValueStore {
9 type Target = ThreadSafeConnection<KeyValueStore>;
10
11 fn deref(&self) -> &Self::Target {
12 &self.0
13 }
14}
15
16lazy_static::lazy_static! {
17 pub static ref KEY_VALUE_STORE: KeyValueStore = KeyValueStore(if cfg!(any(test, feature = "test-support")) {
18 smol::block_on(open_memory_db("KEY_VALUE_STORE"))
19 } else {
20 smol::block_on(open_file_db())
21 });
22}
23
24impl Domain for KeyValueStore {
25 fn name() -> &'static str {
26 "kvp"
27 }
28
29 fn migrations() -> &'static [&'static str] {
30 &[sql!(
31 CREATE TABLE kv_store(
32 key TEXT PRIMARY KEY,
33 value TEXT NOT NULL
34 ) STRICT;
35 )]
36 }
37}
38
39impl KeyValueStore {
40 query! {
41 pub fn read_kvp(key: &str) -> Result<Option<String>> {
42 SELECT value FROM kv_store WHERE key = (?)
43 }
44 }
45
46 query! {
47 pub async fn write_kvp(key: String, value: String) -> Result<()> {
48 INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))
49 }
50 }
51
52 query! {
53 pub async fn delete_kvp(key: String) -> Result<()> {
54 DELETE FROM kv_store WHERE key = (?)
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use crate::kvp::KeyValueStore;
62
63 #[gpui::test]
64 async fn test_kvp() {
65 let db = KeyValueStore(crate::open_memory_db("test_kvp").await);
66
67 assert_eq!(db.read_kvp("key-1").unwrap(), None);
68
69 db.write_kvp("key-1".to_string(), "one".to_string())
70 .await
71 .unwrap();
72 assert_eq!(db.read_kvp("key-1").unwrap(), Some("one".to_string()));
73
74 db.write_kvp("key-1".to_string(), "one-2".to_string())
75 .await
76 .unwrap();
77 assert_eq!(db.read_kvp("key-1").unwrap(), Some("one-2".to_string()));
78
79 db.write_kvp("key-2".to_string(), "two".to_string())
80 .await
81 .unwrap();
82 assert_eq!(db.read_kvp("key-2").unwrap(), Some("two".to_string()));
83
84 db.delete_kvp("key-1".to_string()).await.unwrap();
85 assert_eq!(db.read_kvp("key-1").unwrap(), None);
86 }
87}