Refactored workspaces API and corrected method headers + fixed bug caused by migration failures

Mikayla Maki and kay@zed.dev created

co-authored-by: kay@zed.dev

Change summary

crates/db/examples/serialize-pane.rs      |  4 +---
crates/db/examples/serialize_workspace.rs | 24 +++++++-----------------
crates/db/src/kvp.rs                      |  4 ----
crates/db/src/pane.rs                     |  8 +-------
crates/db/src/workspace.rs                | 10 +++-------
5 files changed, 12 insertions(+), 38 deletions(-)

Detailed changes

crates/db/examples/serialize-pane.rs 🔗

@@ -14,9 +14,7 @@ fn main() -> anyhow::Result<()> {
     let f = File::create(file)?;
     drop(f);
 
-    let workspace = db.make_new_workspace::<String>(&[]);
-
-    db.update_worktrees(&workspace.workspace_id, &["/tmp"]);
+    let workspace = db.workspace_for_roots(&["/tmp"]);
 
     db.save_dock_pane(SerializedDockPane {
         workspace: workspace.workspace_id,

crates/db/examples/serialize_workspace.rs 🔗

@@ -15,29 +15,19 @@ fn main() -> anyhow::Result<()> {
     db.write_kvp("test", "1")?;
     db.write_kvp("test-2", "2")?;
 
-    let workspace_1 = db.make_new_workspace::<String>(&[]);
-    let workspace_2 = db.make_new_workspace::<String>(&[]);
-    let workspace_3 = db.make_new_workspace::<String>(&[]);
-    let workspace_4 = db.make_new_workspace::<String>(&[]);
-    let workspace_5 = db.make_new_workspace::<String>(&[]);
-    let workspace_6 = db.make_new_workspace::<String>(&[]);
-    let workspace_7 = db.make_new_workspace::<String>(&[]);
-
-    // Order scrambled + sleeps added because sqlite only has 1 second resolution on
-    // their timestamps
-    db.update_worktrees(&workspace_7.workspace_id, &["/tmp2"]);
+    db.workspace_for_roots(&["/tmp1"]);
     sleep(Duration::from_secs(1));
-    db.update_worktrees(&workspace_1.workspace_id, &["/tmp1"]);
+    db.workspace_for_roots(&["/tmp1", "/tmp2"]);
     sleep(Duration::from_secs(1));
-    db.update_worktrees(&workspace_2.workspace_id, &["/tmp1", "/tmp2"]);
+    db.workspace_for_roots(&["/tmp1", "/tmp2", "/tmp3"]);
     sleep(Duration::from_secs(1));
-    db.update_worktrees(&workspace_3.workspace_id, &["/tmp1", "/tmp2", "/tmp3"]);
+    db.workspace_for_roots(&["/tmp2", "/tmp3"]);
     sleep(Duration::from_secs(1));
-    db.update_worktrees(&workspace_4.workspace_id, &["/tmp2", "/tmp3"]);
+    db.workspace_for_roots(&["/tmp2", "/tmp3", "/tmp4"]);
     sleep(Duration::from_secs(1));
-    db.update_worktrees(&workspace_5.workspace_id, &["/tmp2", "/tmp3", "/tmp4"]);
+    db.workspace_for_roots(&["/tmp2", "/tmp4"]);
     sleep(Duration::from_secs(1));
-    db.update_worktrees(&workspace_6.workspace_id, &["/tmp2", "/tmp4"]);
+    db.workspace_for_roots(&["/tmp2"]);
 
     db.write_to(file).ok();
 

crates/db/src/kvp.rs 🔗

@@ -4,14 +4,10 @@ use rusqlite::OptionalExtension;
 use super::Db;
 
 pub(crate) const KVP_M_1: &str = "
-BEGIN TRANSACTION; 
-
 CREATE TABLE kv_store(
     key TEXT PRIMARY KEY,
     value TEXT NOT NULL
 ) STRICT;
-
-COMMIT;
 ";
 
 impl Db {

crates/db/src/pane.rs 🔗

@@ -75,8 +75,6 @@ pub struct SerializedPane {
 }
 
 pub(crate) const PANE_M_1: &str = "
-BEGIN TRANSACTION;
-
 CREATE TABLE dock_panes(
     dock_pane_id INTEGER PRIMARY KEY,
     workspace_id INTEGER NOT NULL,
@@ -131,8 +129,6 @@ CREATE TABLE dock_items(
     FOREIGN KEY(dock_pane_id) REFERENCES dock_panes(dock_pane_id) ON DELETE CASCADE,
     FOREIGN KEY(item_id) REFERENCES items(item_id)ON DELETE CASCADE
 ) STRICT;
-
-COMMIT;
 ";
 
 #[derive(Default, Debug)]
@@ -222,9 +218,7 @@ mod tests {
     fn test_basic_dock_pane() {
         let db = Db::open_in_memory();
 
-        let workspace = db.make_new_workspace::<String>(&[]);
-
-        db.update_worktrees(&workspace.workspace_id, &["/tmp"]);
+        let workspace = db.workspace_for_roots(&["/tmp"]);
 
         db.save_dock_pane(SerializedDockPane {
             workspace: workspace.workspace_id,

crates/db/src/workspace.rs 🔗

@@ -17,8 +17,6 @@ use super::Db;
 // you might want to update some of the parsing code as well, I've left the variations in but commented
 // out
 pub(crate) const WORKSPACE_M_1: &str = "
-BEGIN TRANSACTION; 
-
 CREATE TABLE workspaces(
     workspace_id INTEGER PRIMARY KEY,
     timestamp TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL
@@ -30,8 +28,6 @@ CREATE TABLE worktree_roots(
     FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) ON DELETE CASCADE
     PRIMARY KEY(worktree_root, workspace_id)
 ) STRICT;
-
-COMMIT;
 ";
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
@@ -68,7 +64,7 @@ impl Db {
         }
     }
 
-    pub fn make_new_workspace<P>(&self, worktree_roots: &[P]) -> SerializedWorkspace
+    fn make_new_workspace<P>(&self, worktree_roots: &[P]) -> SerializedWorkspace
     where
         P: AsRef<Path> + Debug,
     {
@@ -158,7 +154,7 @@ impl Db {
         });
     }
 
-    pub fn last_workspace_id(&self) -> Option<WorkspaceId> {
+    fn last_workspace_id(&self) -> Option<WorkspaceId> {
         fn logic(connection: &mut Connection) -> Result<Option<WorkspaceId>> {
             let mut stmt = connection
                 .prepare("SELECT workspace_id FROM workspaces ORDER BY timestamp DESC LIMIT 1")?;
@@ -432,7 +428,7 @@ mod tests {
     use super::WorkspaceId;
 
     #[test]
-    fn test_worktree_for_roots() {
+    fn test_new_worktrees_for_roots() {
         let db = Db::open_in_memory();
 
         // Test creation in 0 case