This commit is contained in:
K Simmons 2022-10-20 15:07:58 -07:00 committed by Mikayla Maki
parent b48e28b555
commit 0c466f806c
10 changed files with 302 additions and 45 deletions

View file

@ -1,5 +1,7 @@
use std::{path::Path, sync::Arc};
use crate::pane::{PaneGroupId, PaneId, SerializedPane, SerializedPaneGroup};
use super::Db;
pub(crate) const WORKSPACE_M_1: &str = "
@ -17,28 +19,6 @@ CREATE TABLE worktree_roots(
workspace_id INTEGER NOT NULL,
FOREIGN KEY(workspace_id) REFERENCES workspace_ids(workspace_id)
) STRICT;
CREATE TABLE pane_groups(
workspace_id INTEGER,
group_id INTEGER,
split_direction STRING, -- 'Vertical' / 'Horizontal' /
PRIMARY KEY (workspace_id, group_id)
) STRICT;
CREATE TABLE pane_group_children(
workspace_id INTEGER,
group_id INTEGER,
child_pane_id INTEGER, -- Nullable
child_group_id INTEGER, -- Nullable
PRIMARY KEY (workspace_id, group_id)
) STRICT;
CREATE TABLE pane_items(
workspace_id INTEGER,
pane_id INTEGER,
item_id INTEGER, -- Array
PRIMARY KEY (workspace_id, pane_id)
) STRICT;
";
// Zed stores items with ids which are a combination of a view id during a given run and a workspace id. This
@ -52,18 +32,65 @@ CREATE TABLE pane_items(
// Case 4: Starting Zed with multiple project folders
// > Zed ~/projects/Zed ~/projects/Zed.dev
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct WorkspaceId(usize);
struct WorkspaceRow {
pub workspace_id: WorkspaceId,
pub center_group_id: PaneGroupId,
pub dock_pane_id: PaneId,
}
pub struct SerializedWorkspace {
pub workspace_id: WorkspaceId,
pub center_group: SerializedPaneGroup,
pub dock_pane: Option<SerializedPane>,
}
impl Db {
/// Finds or creates a workspace id for the given set of worktree roots. If the passed worktree roots is empty, return the
/// the last workspace id
pub fn workspace_id(&self, worktree_roots: &[Arc<Path>]) -> WorkspaceId {
pub fn workspace_for_worktree_roots(
&self,
worktree_roots: &[Arc<Path>],
) -> SerializedWorkspace {
// Find the workspace id which is uniquely identified by this set of paths return it if found
// Otherwise:
// Find the max workspace_id and increment it as our new workspace id
// Store in the worktrees table the mapping from this new id to the set of worktree roots
unimplemented!();
if let Some(workspace_id) = self.workspace_id(worktree_roots) {
let workspace_row = self.get_workspace_row(workspace_id);
let center_group = self.get_pane_group(workspace_row.center_group_id);
let dock_pane = self.get_pane(workspace_row.dock_pane_id);
SerializedWorkspace {
workspace_id,
center_group,
dock_pane: Some(dock_pane),
}
} else {
let workspace_id = self.get_next_workspace_id();
let center_group = SerializedPaneGroup {
group_id: PaneGroupId::root(workspace_id),
axis: Default::default(),
children: Default::default(),
};
SerializedWorkspace {
workspace_id,
center_group,
dock_pane: None,
}
}
}
fn get_next_workspace_id(&self) -> WorkspaceId {
unimplemented!()
}
fn workspace_id(&self, worktree_roots: &[Arc<Path>]) -> Option<WorkspaceId> {
unimplemented!()
}
fn get_workspace_row(&self, workspace_id: WorkspaceId) -> WorkspaceRow {
unimplemented!()
}
/// Updates the open paths for the given workspace id. Will garbage collect items from
@ -80,16 +107,12 @@ impl Db {
unimplemented!();
}
/// Returns the previous workspace ids sorted by last modified
/// Returns the previous workspace ids sorted by last modified along with their opened worktree roots
pub fn recent_workspaces(&self) -> Vec<(WorkspaceId, Vec<Arc<Path>>)> {
// Return all the workspace ids and their associated paths ordered by the access timestamp
//ORDER BY timestamps
unimplemented!();
}
pub fn center_pane(&self, workspace: WorkspaceId) -> SerializedPaneGroup {}
pub fn dock_pane(&self, workspace: WorkspaceId) -> SerializedPane {}
}
#[cfg(test)]
@ -104,6 +127,42 @@ mod tests {
use super::WorkspaceId;
fn arc_path(path: &'static str) -> Arc<Path> {
PathBuf::from(path).into()
}
fn test_detect_workspace_id() {
let data = &[
(WorkspaceId(1), vec![arc_path("/tmp")]),
(WorkspaceId(2), vec![arc_path("/tmp"), arc_path("/tmp2")]),
(
WorkspaceId(3),
vec![arc_path("/tmp"), arc_path("/tmp2"), arc_path("/tmp3")],
),
];
let db = Db::open_in_memory();
for (workspace_id, entries) in data {
db.update_worktree_roots(workspace_id, entries); //??
}
assert_eq!(None, db.workspace_id(&[arc_path("/tmp2")]));
assert_eq!(
None,
db.workspace_id(&[arc_path("/tmp2"), arc_path("/tmp3")])
);
assert_eq!(Some(WorkspaceId(1)), db.workspace_id(&[arc_path("/tmp")]));
assert_eq!(
Some(WorkspaceId(2)),
db.workspace_id(&[arc_path("/tmp"), arc_path("/tmp2")])
);
assert_eq!(
Some(WorkspaceId(3)),
db.workspace_id(&[arc_path("/tmp"), arc_path("/tmp2"), arc_path("/tmp3")])
);
}
fn test_tricky_overlapping_updates() {
// DB state:
// (/tree) -> ID: 1
@ -117,10 +176,6 @@ mod tests {
// (/tree2, /tree3) -> ID: 2
// Get rid of 3 for garbage collection
fn arc_path(path: &'static str) -> Arc<Path> {
PathBuf::from(path).into()
}
let data = &[
(WorkspaceId(1), vec![arc_path("/tmp")]),
(WorkspaceId(2), vec![arc_path("/tmp"), arc_path("/tmp2")]),
@ -131,18 +186,18 @@ mod tests {
for (workspace_id, entries) in data {
db.update_worktree_roots(workspace_id, entries); //??
assert_eq!(&db.workspace_id(&[]), workspace_id)
assert_eq!(&db.workspace_id(&[]), &Some(*workspace_id))
}
for (workspace_id, entries) in data {
assert_eq!(&db.workspace_id(entries.as_slice()), workspace_id);
assert_eq!(&db.workspace_id(entries.as_slice()), &Some(*workspace_id));
}
db.update_worktree_roots(&WorkspaceId(2), &[arc_path("/tmp2")]);
// todo!(); // make sure that 3 got garbage collected
assert_eq!(db.workspace_id(&[arc_path("/tmp2")]), WorkspaceId(2));
assert_eq!(db.workspace_id(&[arc_path("/tmp")]), WorkspaceId(1));
assert_eq!(db.workspace_id(&[arc_path("/tmp2")]), Some(WorkspaceId(2)));
assert_eq!(db.workspace_id(&[arc_path("/tmp")]), Some(WorkspaceId(1)));
let recent_workspaces = db.recent_workspaces();
assert_eq!(recent_workspaces.get(0).unwrap().0, WorkspaceId(2));