kvp.rs

  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}