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