Touched up sql macro

This commit is contained in:
Mikayla Maki 2022-11-21 10:38:16 -08:00
parent 76c42af62a
commit 37174f45f0
4 changed files with 76 additions and 53 deletions

View file

@ -82,36 +82,31 @@ macro_rules! connection {
} }
#[macro_export] #[macro_export]
macro_rules! exec_method { macro_rules! sql_method {
($id:ident(): $sql:literal) => { ($id:ident() -> Result<()>: $sql:literal) => {
pub fn $id(&self) -> $crate::sqlez::anyhow::Result<()> { pub fn $id(&self) -> $crate::sqlez::anyhow::Result<()> {
use $crate::anyhow::Context; use $crate::anyhow::Context;
self.exec($sql)?() self.exec($sql)?().context(::std::format!(
.context(::std::format!( "Error in {}, exec failed to execute or parse for: {}",
"Error in {}, exec failed to execute or parse for: {}", ::std::stringify!($id),
::std::stringify!($id), ::std::stringify!($sql),
::std::stringify!($sql), ))
)) }
}
}; };
($id:ident($($arg:ident: $arg_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<()> { pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result<()> {
use $crate::anyhow::Context; use $crate::anyhow::Context;
self.exec_bound::<($($arg_type),+)>($sql)?(($($arg),+)) self.exec_bound::<($($arg_type),+)>($sql)?(($($arg),+))
.context(::std::format!( .context(::std::format!(
"Error in {}, exec_bound failed to execute or parse for: {}", "Error in {}, exec_bound failed to execute or parse for: {}",
::std::stringify!($id), ::std::stringify!($id),
::std::stringify!($sql), ::std::stringify!($sql),
)) ))
} }
}; };
} ($id:ident() -> Result<Vec<$return_type:ty>>: $sql:literal) => {
#[macro_export]
macro_rules! select_method {
($id:ident() -> $return_type:ty: $sql:literal) => {
pub fn $id(&self) -> $crate::sqlez::anyhow::Result<Vec<$return_type>> { pub fn $id(&self) -> $crate::sqlez::anyhow::Result<Vec<$return_type>> {
use $crate::anyhow::Context; 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<Vec<$return_type:ty>>: $sql:literal) => {
pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result<Vec<$return_type>> { pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result<Vec<$return_type>> {
use $crate::anyhow::Context; use $crate::anyhow::Context;
@ -135,11 +130,7 @@ macro_rules! select_method {
)) ))
} }
}; };
} ($id:ident() -> Result<Option<$return_type:ty>>: $sql:literal) => {
#[macro_export]
macro_rules! select_row_method {
($id:ident() -> $return_type:ty: $sql:literal) => {
pub fn $id(&self) -> $crate::sqlez::anyhow::Result<Option<$return_type>> { pub fn $id(&self) -> $crate::sqlez::anyhow::Result<Option<$return_type>> {
use $crate::anyhow::Context; 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<Option<$return_type:ty>>: $sql:literal) => {
pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result<Option<$return_type>> { pub fn $id(&self, $($arg: $arg_type),+) -> $crate::sqlez::anyhow::Result<Option<$return_type>> {
use $crate::anyhow::Context; use $crate::anyhow::Context;

View file

@ -1,7 +1,7 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use db::{connection, exec_method}; use db::{connection, sql_method};
use indoc::indoc; use indoc::indoc;
use sqlez::domain::Domain; use sqlez::domain::Domain;
use workspace::{ItemId, Workspace, WorkspaceId}; use workspace::{ItemId, Workspace, WorkspaceId};
@ -39,8 +39,9 @@ impl EditorDb {
.context("Path not found for serialized editor") .context("Path not found for serialized editor")
} }
exec_method!(save_path(item_id: ItemId, workspace_id: WorkspaceId, path: &Path): sql_method! {
"INSERT OR REPLACE INTO editors(item_id, workspace_id, path) save_path(item_id: ItemId, workspace_id: WorkspaceId, path: &Path) -> Result<()>:
VALUES (?, ?, ?)" "INSERT OR REPLACE INTO editors(item_id, workspace_id, path)
); VALUES (?, ?, ?)"
}
} }

View file

@ -1,6 +1,6 @@
use std::path::{Path, PathBuf}; 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}; use workspace::{ItemId, Workspace, WorkspaceId};
@ -28,16 +28,16 @@ impl Domain for Terminal {
} }
impl TerminalDb { impl TerminalDb {
exec_method!( sql_method! {
save_working_directory(item_id: ItemId, workspace_id: WorkspaceId, working_directory: &Path): save_working_directory(item_id: ItemId, workspace_id: WorkspaceId, working_directory: &Path) -> Result<()>:
"INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) "INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory)
VALUES (?1, ?2, ?3)" VALUES (?1, ?2, ?3)"
); }
select_row_method!( sql_method! {
get_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> PathBuf: get_working_directory(item_id: ItemId, workspace_id: WorkspaceId) -> Result<Option<PathBuf>>:
"SELECT working_directory "SELECT working_directory
FROM terminals FROM terminals
WHERE item_id = ? AND workspace_id = ?" WHERE item_id = ? AND workspace_id = ?"
); }
} }

View file

@ -5,7 +5,7 @@ pub mod model;
use std::path::Path; use std::path::Path;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use db::{connection, select_row_method}; use db::{connection, sql_method};
use gpui::Axis; use gpui::Axis;
use indoc::indoc; use indoc::indoc;
@ -190,10 +190,10 @@ impl WorkspaceDb {
.log_err(); .log_err();
} }
select_row_method!( sql_method! {
next_id() -> WorkspaceId: next_id() -> Result<Option<WorkspaceId>>:
"INSERT INTO workspaces DEFAULT VALUES RETURNING workspace_id" "INSERT INTO workspaces DEFAULT VALUES RETURNING workspace_id"
); }
/// Returns the previous workspace ids sorted by last modified along with their opened worktree roots /// 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)> { pub fn recent_workspaces(&self, limit: usize) -> Vec<(WorkspaceId, WorkspaceLocation)> {
@ -384,6 +384,37 @@ mod tests {
use super::*; 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] #[test]
fn test_workspace_id_stability() { fn test_workspace_id_stability() {
env_logger::try_init().ok(); env_logger::try_init().ok();
@ -439,19 +470,19 @@ mod tests {
}); });
db.save_workspace(&workspace_2); 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 = ?") .select_row_bound::<_, String>("SELECT text FROM test_table WHERE workspace_id = ?")
.unwrap()(2) .unwrap()(2)
.unwrap() .unwrap()
.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 = ?") .select_row_bound::<_, String>("SELECT text FROM test_table WHERE workspace_id = ?")
.unwrap()(1) .unwrap()(1)
.unwrap() .unwrap()
.unwrap(); .unwrap();
assert_eq!(test_text_2, "test-text-1"); assert_eq!(test_text_1, "test-text-1");
} }
#[test] #[test]