From 2c47bd4a9764ca8a8369bf3c52eefa59edbe3d8c Mon Sep 17 00:00:00 2001 From: Kay Simmons Date: Fri, 16 Dec 2022 15:45:17 -0800 Subject: [PATCH] Clear stale projects if they no longer exist --- crates/db/src/query.rs | 4 +- crates/recent_projects/src/recent_projects.rs | 42 ++++++++++++------- crates/workspace/src/persistence.rs | 27 +++++++++++- 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/crates/db/src/query.rs b/crates/db/src/query.rs index 731fca15cb..20c2a267ff 100644 --- a/crates/db/src/query.rs +++ b/crates/db/src/query.rs @@ -80,7 +80,7 @@ macro_rules! query { let sql_stmt = $crate::sqlez_macros::sql!($($sql)+); - self.select::<$return_type>(sql_stmt)?(()) + self.select::<$return_type>(sql_stmt)?() .context(::std::format!( "Error in {}, select_row failed to execute or parse for: {}", ::std::stringify!($id), @@ -95,7 +95,7 @@ macro_rules! query { self.write(|connection| { let sql_stmt = $crate::sqlez_macros::sql!($($sql)+); - connection.select::<$return_type>(sql_stmt)?(()) + connection.select::<$return_type>(sql_stmt)?() .context(::std::format!( "Error in {}, select_row failed to execute or parse for: {}", ::std::stringify!($id), diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index 1842540db3..42ff2b2f1c 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -11,9 +11,7 @@ use highlighted_workspace_location::HighlightedWorkspaceLocation; use ordered_float::OrderedFloat; use picker::{Picker, PickerDelegate}; use settings::Settings; -use workspace::{OpenPaths, Workspace, WorkspaceLocation}; - -const RECENT_LIMIT: usize = 100; +use workspace::{OpenPaths, Workspace, WorkspaceLocation, WORKSPACE_DB}; actions!(recent_projects, [Toggle]); @@ -30,14 +28,8 @@ struct RecentProjectsView { } impl RecentProjectsView { - fn new(cx: &mut ViewContext) -> Self { + fn new(workspace_locations: Vec, cx: &mut ViewContext) -> Self { let handle = cx.weak_handle(); - let workspace_locations: Vec = workspace::WORKSPACE_DB - .recent_workspaces(RECENT_LIMIT) - .unwrap_or_default() - .into_iter() - .map(|(_, location)| location) - .collect(); Self { picker: cx.add_view(|cx| { Picker::new("Recent Projects...", handle, cx).with_max_size(800., 1200.) @@ -48,12 +40,30 @@ impl RecentProjectsView { } } - fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { - workspace.toggle_modal(cx, |_, cx| { - let view = cx.add_view(|cx| Self::new(cx)); - cx.subscribe(&view, Self::on_event).detach(); - view - }); + fn toggle(_: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { + cx.spawn(|workspace, mut cx| async move { + let workspace_locations = cx + .background() + .spawn(async { + WORKSPACE_DB + .recent_workspaces_on_disk() + .await + .unwrap_or_default() + .into_iter() + .map(|(_, location)| location) + .collect() + }) + .await; + + workspace.update(&mut cx, |workspace, cx| { + workspace.toggle_modal(cx, |_, cx| { + let view = cx.add_view(|cx| Self::new(workspace_locations, cx)); + cx.subscribe(&view, Self::on_event).detach(); + view + }); + }) + }) + .detach(); } fn on_event( diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index 2d4ae919f9..fcbdb1deba 100644 --- a/crates/workspace/src/persistence.rs +++ b/crates/workspace/src/persistence.rs @@ -196,14 +196,37 @@ impl WorkspaceDb { } query! { - pub fn recent_workspaces(limit: usize) -> Result> { + fn recent_workspaces() -> Result> { SELECT workspace_id, workspace_location FROM workspaces WHERE workspace_location IS NOT NULL ORDER BY timestamp DESC - LIMIT ? } } + + query! { + async fn delete_stale_workspace(id: WorkspaceId) -> Result<()> { + DELETE FROM workspaces + WHERE workspace_id IS ? + } + } + + // Returns the recent locations which are still valid on disk and deletes ones which no longer + // exist. + pub async fn recent_workspaces_on_disk(&self) -> Result> { + let mut result = Vec::new(); + let mut delete_tasks = Vec::new(); + for (id, location) in self.recent_workspaces()? { + if location.paths().iter().all(|path| dbg!(path).exists()) { + result.push((id, location)); + } else { + delete_tasks.push(self.delete_stale_workspace(id)); + } + } + + futures::future::join_all(delete_tasks).await; + Ok(result) + } fn get_center_pane_group(&self, workspace_id: WorkspaceId) -> Result { self.get_pane_group(workspace_id, None)?