diff --git a/crates/db/src/db.rs b/crates/db/src/db.rs index 7ec4a12223..20b2ac142a 100644 --- a/crates/db/src/db.rs +++ b/crates/db/src/db.rs @@ -82,36 +82,31 @@ macro_rules! connection { } #[macro_export] -macro_rules! exec_method { - ($id:ident(): $sql:literal) => { - pub fn $id(&self) -> $crate::sqlez::anyhow::Result<()> { - use $crate::anyhow::Context; +macro_rules! sql_method { + ($id:ident() -> Result<()>: $sql:literal) => { + pub fn $id(&self) -> $crate::sqlez::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), - )) - } + self.exec($sql)?().context(::std::format!( + "Error in {}, exec failed to execute or parse for: {}", + ::std::stringify!($id), + ::std::stringify!($sql), + )) + } }; - ($id:ident($($arg:ident: $arg_type:ty),+): $sql:literal) => { - pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result<()> { - use $crate::anyhow::Context; + ($id:ident($($arg:ident: $arg_type:ty),+) -> Result<()>: $sql:literal) => { + pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::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), - )) - } + 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), + )) + } }; -} - -#[macro_export] -macro_rules! select_method { - ($id:ident() -> $return_type:ty: $sql:literal) => { + ($id:ident() -> Result>: $sql:literal) => { pub fn $id(&self) -> $crate::sqlez::anyhow::Result> { use $crate::anyhow::Context; @@ -123,7 +118,7 @@ macro_rules! select_method { )) } }; - ($id:ident($($arg:ident: $arg_type:ty),+) -> $return_type:ty: $sql:literal) => { + ($id:ident($($arg:ident: $arg_type:ty),+) -> Result>: $sql:literal) => { pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result> { use $crate::anyhow::Context; @@ -135,11 +130,7 @@ macro_rules! select_method { )) } }; -} - -#[macro_export] -macro_rules! select_row_method { - ($id:ident() -> $return_type:ty: $sql:literal) => { + ($id:ident() -> Result>: $sql:literal) => { pub fn $id(&self) -> $crate::sqlez::anyhow::Result> { use $crate::anyhow::Context; @@ -151,7 +142,7 @@ macro_rules! select_row_method { )) } }; - ($id:ident($($arg:ident: $arg_type:ty),+) -> $return_type:ty: $sql:literal) => { + ($id:ident($($arg:ident: $arg_type:ty),+) -> Result>: $sql:literal) => { pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result> { use $crate::anyhow::Context; diff --git a/crates/editor/src/persistence.rs b/crates/editor/src/persistence.rs index 2344037384..b2186e2432 100644 --- a/crates/editor/src/persistence.rs +++ b/crates/editor/src/persistence.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; -use db::{connection, exec_method}; +use db::{connection, sql_method}; use indoc::indoc; use sqlez::domain::Domain; use workspace::{ItemId, Workspace, WorkspaceId}; @@ -39,8 +39,9 @@ impl EditorDb { .context("Path not found for serialized editor") } - exec_method!(save_path(item_id: ItemId, workspace_id: WorkspaceId, path: &Path): - "INSERT OR REPLACE INTO editors(item_id, workspace_id, path) - VALUES (?, ?, ?)" - ); + sql_method! { + save_path(item_id: ItemId, workspace_id: WorkspaceId, path: &Path) -> Result<()>: + "INSERT OR REPLACE INTO editors(item_id, workspace_id, path) + VALUES (?, ?, ?)" + } } diff --git a/crates/terminal/src/persistence.rs b/crates/terminal/src/persistence.rs index d624724e5c..384dcc18e0 100644 --- a/crates/terminal/src/persistence.rs +++ b/crates/terminal/src/persistence.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; -use db::{connection, exec_method, indoc, select_row_method, sqlez::domain::Domain}; +use db::{connection, indoc, sql_method, sqlez::domain::Domain}; use workspace::{ItemId, Workspace, WorkspaceId}; @@ -28,16 +28,16 @@ impl Domain for Terminal { } impl TerminalDb { - exec_method!( - save_working_directory(item_id: ItemId, workspace_id: WorkspaceId, working_directory: &Path): + sql_method! { + save_working_directory(item_id: ItemId, workspace_id: WorkspaceId, working_directory: &Path) -> Result<()>: "INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) VALUES (?1, ?2, ?3)" - ); + } - select_row_method!( - get_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> PathBuf: + sql_method! { + get_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> Result>: "SELECT working_directory FROM terminals WHERE item_id = ? AND workspace_id = ?" - ); + } } diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index 88a894a922..a4073d27d3 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, select_row_method}; +use db::{connection, sql_method}; use gpui::Axis; use indoc::indoc; @@ -190,10 +190,10 @@ impl WorkspaceDb { .log_err(); } - select_row_method!( - next_id() -> WorkspaceId: + sql_method! { + 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 pub fn recent_workspaces(&self, limit: usize) -> Vec<(WorkspaceId, WorkspaceLocation)> { @@ -384,6 +384,37 @@ mod tests { use super::*; + #[test] + fn test_next_id_stability() { + env_logger::try_init().ok(); + + let db = WorkspaceDb(open_memory_db(Some("test_workspace_id_stability"))); + + db.migrate( + "test_table", + &["CREATE TABLE test_table( + text TEXT, + workspace_id INTEGER, + FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) + ON DELETE CASCADE + ) STRICT;"], + ) + .unwrap(); + + let id = db.next_id().unwrap(); + + db.exec_bound("INSERT INTO test_table(text, workspace_id) VALUES (?, ?)") + .unwrap()(("test-text-1", id)) + .unwrap(); + + let test_text_1 = db + .select_row_bound::<_, String>("SELECT text FROM test_table WHERE workspace_id = ?") + .unwrap()(1) + .unwrap() + .unwrap(); + assert_eq!(test_text_1, "test-text-1"); + } + #[test] fn test_workspace_id_stability() { env_logger::try_init().ok(); @@ -439,19 +470,19 @@ mod tests { }); db.save_workspace(&workspace_2); - let test_text_1 = db + let test_text_2 = db .select_row_bound::<_, String>("SELECT text FROM test_table WHERE workspace_id = ?") .unwrap()(2) .unwrap() .unwrap(); - assert_eq!(test_text_1, "test-text-2"); + assert_eq!(test_text_2, "test-text-2"); - let test_text_2 = db + let test_text_1 = db .select_row_bound::<_, String>("SELECT text FROM test_table WHERE workspace_id = ?") .unwrap()(1) .unwrap() .unwrap(); - assert_eq!(test_text_2, "test-text-1"); + assert_eq!(test_text_1, "test-text-1"); } #[test]