From 359b8aaf47573473cce3334d7af48d01eac972df Mon Sep 17 00:00:00 2001 From: Kay Simmons Date: Thu, 24 Nov 2022 00:02:07 -0800 Subject: [PATCH] rename sql_method to query and adjust the syntax to more closely match function definitions --- crates/auto_update/src/auto_update.rs | 11 +- crates/client/src/telemetry.rs | 4 +- crates/db/src/db.rs | 152 +++++++++++++++++--------- crates/db/src/kvp.rs | 76 +++++++------ crates/editor/src/persistence.rs | 24 ++-- crates/terminal/src/persistence.rs | 42 +++---- crates/workspace/src/persistence.rs | 7 +- 7 files changed, 192 insertions(+), 124 deletions(-) diff --git a/crates/auto_update/src/auto_update.rs b/crates/auto_update/src/auto_update.rs index 2a8d2fcf05..d3fcc36c2f 100644 --- a/crates/auto_update/src/auto_update.rs +++ b/crates/auto_update/src/auto_update.rs @@ -297,9 +297,16 @@ impl AutoUpdater { ) -> Task> { cx.background().spawn(async move { if should_show { - KEY_VALUE_STORE.write_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY, "")?; + KEY_VALUE_STORE + .write_kvp( + SHOULD_SHOW_UPDATE_NOTIFICATION_KEY.to_string(), + "".to_string(), + ) + .await?; } else { - KEY_VALUE_STORE.delete_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?; + KEY_VALUE_STORE + .delete_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY.to_string()) + .await?; } Ok(()) }) diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index 0ce1a07f1b..a81f33c604 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -157,7 +157,9 @@ impl Telemetry { device_id } else { let device_id = Uuid::new_v4().to_string(); - KEY_VALUE_STORE.write_kvp("device_id", &device_id)?; + KEY_VALUE_STORE + .write_kvp("device_id".to_string(), device_id.clone()) + .await?; device_id }; diff --git a/crates/db/src/db.rs b/crates/db/src/db.rs index b42b264b56..1da51ef867 100644 --- a/crates/db/src/db.rs +++ b/crates/db/src/db.rs @@ -75,45 +75,59 @@ macro_rules! connection { } #[macro_export] -macro_rules! sql_method { - ($id:ident() -> Result<()>: $sql:expr) => { - pub fn $id(&self) -> $crate::anyhow::Result<()> { +macro_rules! query { + ($vis:vis fn $id:ident() -> Result<()> { $sql:expr }) => { + $vis fn $id(&self) -> $crate::anyhow::Result<()> { use $crate::anyhow::Context; self.exec($sql)?().context(::std::format!( "Error in {}, exec failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident() -> Result<()>: $sql:expr) => { - pub async fn $id(&self) -> $crate::anyhow::Result<()> { + ($vis:vis async fn $id:ident() -> Result<()> { $sql:expr }) => { + $vis async fn $id(&self) -> $crate::anyhow::Result<()> { use $crate::anyhow::Context; self.write(|connection| { connection.exec($sql)?().context(::std::format!( "Error in {}, exec failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident($($arg:ident: $arg_type:ty),+) -> Result<()>: $sql:expr) => { - pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<()> { + ($vis:vis fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result<()> { $sql:expr }) => { + $vis fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<()> { use $crate::anyhow::Context; self.exec_bound::<($($arg_type),+)>($sql)?(($($arg),+)) .context(::std::format!( "Error in {}, exec_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident($($arg:ident: $arg_type:ty),+) -> Result<()>: $sql:expr) => { - pub async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<()> { + ($vis:vis async fn $id:ident($arg:ident: $arg_type:ty) -> Result<()> { $sql:expr }) => { + $vis async fn $id(&self, $arg: $arg_type) -> $crate::anyhow::Result<()> { + use $crate::anyhow::Context; + + self.write(move |connection| { + connection.exec_bound::<$arg_type>($sql)?($arg) + .context(::std::format!( + "Error in {}, exec_bound failed to execute or parse for: {}", + ::std::stringify!($id), + $sql, + )) + }).await + } + }; + ($vis:vis async fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result<()> { $sql:expr }) => { + $vis async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<()> { use $crate::anyhow::Context; self.write(move |connection| { @@ -121,24 +135,24 @@ macro_rules! sql_method { .context(::std::format!( "Error in {}, exec_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident() -> Result>: $sql:expr) => { - pub fn $id(&self) -> $crate::anyhow::Result> { + ($vis:vis fn $id:ident() -> Result> { $sql:expr }) => { + $vis fn $id(&self) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.select::<$return_type>($sql)?(()) .context(::std::format!( "Error in {}, select_row failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident() -> Result>: $sql:expr) => { + ($vis:vis async fn $id:ident() -> Result> { $sql:expr }) => { pub async fn $id(&self) -> $crate::anyhow::Result> { use $crate::anyhow::Context; @@ -147,25 +161,25 @@ macro_rules! sql_method { .context(::std::format!( "Error in {}, select_row failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident($($arg:ident: $arg_type:ty),+) -> Result>: $sql:expr) => { - pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { + ($vis:vis fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result> { $sql:expr }) => { + $vis fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.select_bound::<($($arg_type),+), $return_type>($sql)?(($($arg),+)) .context(::std::format!( "Error in {}, exec_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident($($arg:ident: $arg_type:ty),+) -> Result>: $sql:expr) => { - pub async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { + ($vis:vis async fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result> { $sql:expr }) => { + $vis async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.write(|connection| { @@ -173,25 +187,25 @@ macro_rules! sql_method { .context(::std::format!( "Error in {}, exec_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident() -> Result>: $sql:expr) => { - pub fn $id(&self) -> $crate::anyhow::Result> { + ($vis:vis fn $id:ident() -> Result> { $sql:expr }) => { + $vis fn $id(&self) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.select_row::<$return_type>($sql)?() .context(::std::format!( "Error in {}, select_row failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident() -> Result>: $sql:expr) => { - pub async fn $id(&self) -> $crate::anyhow::Result> { + ($vis:vis async fn $id:ident() -> Result> { $sql:expr }) => { + $vis async fn $id(&self) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.write(|connection| { @@ -199,57 +213,70 @@ macro_rules! sql_method { .context(::std::format!( "Error in {}, select_row failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident($($arg:ident: $arg_type:ty),+) -> Result>: $sql:expr) => { - pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { + ($vis:vis fn $id:ident($arg:ident: $arg_type:ty) -> Result> { $sql:expr }) => { + $vis fn $id(&self, $arg: $arg_type) -> $crate::anyhow::Result> { + use $crate::anyhow::Context; + + self.select_row_bound::<$arg_type, $return_type>($sql)?($arg) + .context(::std::format!( + "Error in {}, select_row_bound failed to execute or parse for: {}", + ::std::stringify!($id), + $sql, + )) + + } + }; + ($vis:vis fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result> { $sql:expr }) => { + $vis fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.select_row_bound::<($($arg_type),+), $return_type>($sql)?(($($arg),+)) .context(::std::format!( "Error in {}, select_row_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident($($arg:ident: $arg_type:ty),+) -> Result>: $sql:expr) => { - pub async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { + ($vis:vis async fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result> { $sql:expr }) => { + $vis async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result> { use $crate::anyhow::Context; self.write(|connection| { - connection.select_row_bound::<($($arg_type),+), $return_type>($sql)?(($($arg),+)) + connection.select_row_bound::<($($arg_type),+), $return_type>(indoc! { $sql })?(($($arg),+)) .context(::std::format!( "Error in {}, select_row_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident() -> Result<$return_type:ty>: $sql:expr) => { - pub fn $id(&self) -> $crate::anyhow::Result<$return_type> { + ($vis:vis fn $id:ident() -> Result<$return_type:ty> { $sql:expr }) => { + $vis fn $id(&self) -> $crate::anyhow::Result<$return_type> { use $crate::anyhow::Context; - self.select_row::<$return_type>($sql)?() + self.select_row::<$return_type>(indoc! { $sql })?() .context(::std::format!( "Error in {}, select_row_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, ))? .context(::std::format!( "Error in {}, select_row_bound expected single row result but found none for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident() -> Result<$return_type:ty>: $sql:expr) => { - pub async fn $id(&self) -> $crate::anyhow::Result<$return_type> { + ($vis:vis async fn $id:ident() -> Result<$return_type:ty> { $sql:expr }) => { + $vis async fn $id(&self) -> $crate::anyhow::Result<$return_type> { use $crate::anyhow::Context; self.write(|connection| { @@ -257,35 +284,52 @@ macro_rules! sql_method { .context(::std::format!( "Error in {}, select_row_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, ))? .context(::std::format!( "Error in {}, select_row_bound expected single row result but found none for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } }; - ($id:ident($($arg:ident: $arg_type:ty),+) -> Result<$return_type:ty>: $sql:expr) => { - pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<$return_type> { + ($vis:vis fn $id:ident($arg:ident: $arg_type:ty) -> Result<$return_type:ty> { $sql:expr }) => { + pub fn $id(&self, $arg: $arg_type) -> $crate::anyhow::Result<$return_type> { + use $crate::anyhow::Context; + + self.select_row_bound::<$arg_type, $return_type>($sql)?($arg) + .context(::std::format!( + "Error in {}, select_row_bound failed to execute or parse for: {}", + ::std::stringify!($id), + $sql, + ))? + .context(::std::format!( + "Error in {}, select_row_bound expected single row result but found none for: {}", + ::std::stringify!($id), + $sql, + )) + } + }; + ($vis:vis fn $id:ident($($arg:ident: $arg_type:ty),+) -> Result<$return_type:ty> { $sql:expr }) => { + $vis fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<$return_type> { use $crate::anyhow::Context; self.select_row_bound::<($($arg_type),+), $return_type>($sql)?(($($arg),+)) .context(::std::format!( "Error in {}, select_row_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, ))? .context(::std::format!( "Error in {}, select_row_bound expected single row result but found none for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) } }; - (async $id:ident($($arg:ident: $arg_type:ty),+) -> Result<$return_type:ty>: $sql:expr) => { - pub async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<$return_type> { + ($vis:vis fn async $id:ident($($arg:ident: $arg_type:ty),+) -> Result<$return_type:ty> { $sql:expr }) => { + $vis async fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<$return_type> { use $crate::anyhow::Context; self.write(|connection| { @@ -293,12 +337,12 @@ macro_rules! sql_method { .context(::std::format!( "Error in {}, select_row_bound failed to execute or parse for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, ))? .context(::std::format!( "Error in {}, select_row_bound expected single row result but found none for: {}", ::std::stringify!($id), - ::std::stringify!($sql), + $sql, )) }).await } diff --git a/crates/db/src/kvp.rs b/crates/db/src/kvp.rs index dd82c17615..1763ed964c 100644 --- a/crates/db/src/kvp.rs +++ b/crates/db/src/kvp.rs @@ -1,16 +1,26 @@ -use anyhow::Result; use indoc::indoc; use sqlez::{domain::Domain, thread_safe_connection::ThreadSafeConnection}; -use std::ops::Deref; -lazy_static::lazy_static! { - pub static ref KEY_VALUE_STORE: KeyValueStore = - KeyValueStore(crate::open_file_db()); +use crate::{open_file_db, open_memory_db, query}; + +pub struct KeyValueStore(ThreadSafeConnection); + +impl std::ops::Deref for KeyValueStore { + type Target = ThreadSafeConnection; + + fn deref(&self) -> &Self::Target { + &self.0 + } } -#[derive(Clone)] -pub struct KeyValueStore(ThreadSafeConnection); +lazy_static::lazy_static! { + pub static ref KEY_VALUE_STORE: KeyValueStore = KeyValueStore(if cfg!(any(test, feature = "test-support")) { + open_memory_db(stringify!($id)) + } else { + open_file_db() + }); +} impl Domain for KeyValueStore { fn name() -> &'static str { @@ -27,56 +37,52 @@ impl Domain for KeyValueStore { } } -impl Deref for KeyValueStore { - type Target = ThreadSafeConnection; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - impl KeyValueStore { - pub fn read_kvp(&self, key: &str) -> Result> { - self.select_row_bound("SELECT value FROM kv_store WHERE key = (?)")?(key) + query! { + pub fn read_kvp(key: &str) -> Result> { + "SELECT value FROM kv_store WHERE key = (?)" + } } - pub fn write_kvp(&self, key: &str, value: &str) -> Result<()> { - self.exec_bound("INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))")?(( - key, value, - ))?; - - Ok(()) + query! { + pub async fn write_kvp(key: String, value: String) -> Result<()> { + "INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))" + } } - pub fn delete_kvp(&self, key: &str) -> Result<()> { - self.exec_bound("DELETE FROM kv_store WHERE key = (?)")?(key) + query! { + pub async fn delete_kvp(key: String) -> Result<()> { + "DELETE FROM kv_store WHERE key = (?)" + } } } #[cfg(test)] mod tests { - use anyhow::Result; - use crate::kvp::KeyValueStore; - #[test] - fn test_kvp() -> Result<()> { + #[gpui::test] + async fn test_kvp() { let db = KeyValueStore(crate::open_memory_db("test_kvp")); assert_eq!(db.read_kvp("key-1").unwrap(), None); - db.write_kvp("key-1", "one").unwrap(); + db.write_kvp("key-1".to_string(), "one".to_string()) + .await + .unwrap(); assert_eq!(db.read_kvp("key-1").unwrap(), Some("one".to_string())); - db.write_kvp("key-1", "one-2").unwrap(); + db.write_kvp("key-1".to_string(), "one-2".to_string()) + .await + .unwrap(); assert_eq!(db.read_kvp("key-1").unwrap(), Some("one-2".to_string())); - db.write_kvp("key-2", "two").unwrap(); + db.write_kvp("key-2".to_string(), "two".to_string()) + .await + .unwrap(); assert_eq!(db.read_kvp("key-2").unwrap(), Some("two".to_string())); - db.delete_kvp("key-1").unwrap(); + db.delete_kvp("key-1".to_string()).await.unwrap(); assert_eq!(db.read_kvp("key-1").unwrap(), None); - - Ok(()) } } diff --git a/crates/editor/src/persistence.rs b/crates/editor/src/persistence.rs index b2f76294aa..548be88c80 100644 --- a/crates/editor/src/persistence.rs +++ b/crates/editor/src/persistence.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use db::{connection, sql_method}; +use db::{connection, query}; use indoc::indoc; use sqlez::domain::Domain; use workspace::{ItemId, Workspace, WorkspaceId}; @@ -31,17 +31,21 @@ impl Domain for Editor { } impl EditorDb { - sql_method! { - get_path(item_id: ItemId, workspace_id: WorkspaceId) -> Result: - indoc! {" - SELECT path FROM editors - WHERE item_id = ? AND workspace_id = ?"} + query! { + pub fn get_path(item_id: ItemId, workspace_id: WorkspaceId) -> Result { + indoc!{" + SELECT path FROM editors + WHERE item_id = ? AND workspace_id = ? + "} + } } - sql_method! { - async save_path(item_id: ItemId, workspace_id: WorkspaceId, path: PathBuf) -> Result<()>: - indoc! {" + query! { + pub async fn save_path(item_id: ItemId, workspace_id: WorkspaceId, path: PathBuf) -> Result<()> { + indoc!{" INSERT OR REPLACE INTO editors(item_id, workspace_id, path) - VALUES (?, ?, ?)"} + VALUES (?, ?, ?) + "} + } } } diff --git a/crates/terminal/src/persistence.rs b/crates/terminal/src/persistence.rs index 1e9b846f38..5fb7758bec 100644 --- a/crates/terminal/src/persistence.rs +++ b/crates/terminal/src/persistence.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use db::{connection, indoc, sql_method, sqlez::domain::Domain}; +use db::{connection, indoc, query, sqlez::domain::Domain}; use workspace::{ItemId, Workspace, WorkspaceId}; @@ -28,36 +28,40 @@ impl Domain for Terminal { } impl TerminalDb { - sql_method! { - async update_workspace_id( + query! { + pub async fn update_workspace_id( new_id: WorkspaceId, old_id: WorkspaceId, item_id: ItemId - ) -> Result<()>: - indoc! {" - UPDATE terminals - SET workspace_id = ? - WHERE workspace_id = ? AND item_id = ? - "} + ) -> Result<()> { + indoc!{" + UPDATE terminals + SET workspace_id = ? + WHERE workspace_id = ? AND item_id = ? + "} + } } - sql_method! { - async save_working_directory( + query! { + pub async fn save_working_directory( item_id: ItemId, workspace_id: WorkspaceId, - working_directory: PathBuf) -> Result<()>: - indoc!{" - INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) - VALUES (?1, ?2, ?3) - "} + working_directory: PathBuf + ) -> Result<()> { + indoc!{" + INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) + VALUES (?1, ?2, ?3) + "} + } } - sql_method! { - get_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> Result>: + query! { + pub fn get_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> Result> { indoc!{" SELECT working_directory - FROM terminals + FROM terminals WHERE item_id = ? AND workspace_id = ? "} + } } } diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index 66b3622119..17b0aad13f 100644 --- a/crates/workspace/src/persistence.rs +++ b/crates/workspace/src/persistence.rs @@ -5,7 +5,7 @@ pub mod model; use std::path::Path; use anyhow::{anyhow, bail, Context, Result}; -use db::{connection, sql_method, sqlez::connection::Connection}; +use db::{connection, query, sqlez::connection::Connection}; use gpui::Axis; use indoc::indoc; @@ -201,9 +201,10 @@ impl WorkspaceDb { .await; } - sql_method! { - async next_id() -> Result: + query! { + pub async fn next_id() -> Result { "INSERT INTO workspaces DEFAULT VALUES RETURNING workspace_id" + } } /// Returns the previous workspace ids sorted by last modified along with their opened worktree roots