From 79622cf698a1c831341f6e3906005ddbb54c55d8 Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Fri, 24 Mar 2023 09:04:57 +0000 Subject: [PATCH] Delete all instances of a command (#797) * Delete all instances of a command Our search command will de-dupe results by default. But... This isn't great for deleting! You don't want to run it over-and-over-and-over until all commands are deleted. Loop the query, and keep on deleting what it returns until they are all gone. * Optimize delete upload It was running a request for every element, on every sync lol Only push a delete if needed Future: push all deletes in one request --- atuin-client/src/database.rs | 1 + atuin-client/src/sync.rs | 7 +++++++ src/command/client/search.rs | 32 +++++++++++++++++++++++++------- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/atuin-client/src/database.rs b/atuin-client/src/database.rs index 4135646..bb4d9df 100644 --- a/atuin-client/src/database.rs +++ b/atuin-client/src/database.rs @@ -460,6 +460,7 @@ impl Database for Sqlite { ]) .group_by("command") .group_by("exit") + .and_where("deleted_at is null") .order_desc("timestamp"); let query = query.sql().expect("bug in list query. please report"); diff --git a/atuin-client/src/sync.rs b/atuin-client/src/sync.rs index 1c0acaf..474084d 100644 --- a/atuin-client/src/sync.rs +++ b/atuin-client/src/sync.rs @@ -111,6 +111,9 @@ async fn sync_upload( ) -> Result<()> { debug!("starting sync upload"); + let remote_status = client.status().await?; + let remote_deleted: HashSet = HashSet::from_iter(remote_status.deleted.clone()); + let initial_remote_count = client.count().await?; let mut remote_count = initial_remote_count; @@ -157,6 +160,10 @@ async fn sync_upload( let deleted = db.deleted().await?; for i in deleted { + if remote_deleted.contains(&i.id) { + continue; + } + info!("deleting {} on remote", i.id); client.delete_history(i).await?; } diff --git a/src/command/client/search.rs b/src/command/client/search.rs index dd6fcb3..50dfec1 100644 --- a/src/command/client/search.rs +++ b/src/command/client/search.rs @@ -102,14 +102,15 @@ impl Cmd { eprintln!("{item}"); } else { let list_mode = ListMode::from_flags(self.human, self.cmd_only); - let entries = run_non_interactive( + + let mut entries = run_non_interactive( settings, - self.cwd, + self.cwd.clone(), self.exit, self.exclude_exit, - self.exclude_cwd, - self.before, - self.after, + self.exclude_cwd.clone(), + self.before.clone(), + self.after.clone(), self.limit, &self.query, db, @@ -125,8 +126,25 @@ impl Cmd { // delete it // it only took me _years_ to add this // sorry - for entry in entries { - db.delete(entry).await?; + while !entries.is_empty() { + for entry in &entries { + eprintln!("deleting {}", entry.id); + db.delete(entry.clone()).await?; + } + + entries = run_non_interactive( + settings, + self.cwd.clone(), + self.exit, + self.exclude_exit, + self.exclude_cwd.clone(), + self.before.clone(), + self.after.clone(), + self.limit, + &self.query, + db, + ) + .await?; } } else { super::history::print_list(&entries, list_mode, self.format.as_deref());