diff --git a/atuin-client/src/api_client.rs b/atuin-client/src/api_client.rs index 7b373599..affb3c98 100644 --- a/atuin-client/src/api_client.rs +++ b/atuin-client/src/api_client.rs @@ -286,6 +286,8 @@ impl<'a> Client<'a> { let url = format!("{}/api/v0/record", self.sync_addr); let url = Url::parse(url.as_str())?; + debug!("uploading {} records to {url}", records.len()); + let resp = self.client.post(url).json(records).send().await?; handle_resp_error(resp).await?; diff --git a/atuin-client/src/history/store.rs b/atuin-client/src/history/store.rs index a7785452..ab88182a 100644 --- a/atuin-client/src/history/store.rs +++ b/atuin-client/src/history/store.rs @@ -114,7 +114,7 @@ impl HistoryStore { } } - async fn push_record(&self, record: HistoryRecord) -> Result { + async fn push_record(&self, record: HistoryRecord) -> Result<(RecordId, RecordIdx)> { let bytes = record.serialize()?; let idx = self .store @@ -130,20 +130,22 @@ impl HistoryStore { .data(bytes) .build(); + let id = record.id; + self.store .push(&record.encrypt::(&self.encryption_key)) .await?; - Ok(idx) + Ok((id, idx)) } - pub async fn delete(&self, id: HistoryId) -> Result { + pub async fn delete(&self, id: HistoryId) -> Result<(RecordId, RecordIdx)> { let record = HistoryRecord::Delete(id); self.push_record(record).await } - pub async fn push(&self, history: History) -> Result { + pub async fn push(&self, history: History) -> Result<(RecordId, RecordIdx)> { // TODO(ellie): move the history store to its own file // it's tiny rn so fine as is let record = HistoryRecord::Create(history); diff --git a/atuin/src/command/client.rs b/atuin/src/command/client.rs index 6292d263..38048504 100644 --- a/atuin/src/command/client.rs +++ b/atuin/src/command/client.rs @@ -89,7 +89,7 @@ impl Cmd { Self::History(history) => history.run(&settings, &db, sqlite_store).await, Self::Import(import) => import.run(&db).await, Self::Stats(stats) => stats.run(&db, &settings).await, - Self::Search(search) => search.run(db, &mut settings).await, + Self::Search(search) => search.run(db, &mut settings, sqlite_store).await, #[cfg(feature = "sync")] Self::Sync(sync) => sync.run(settings, &db, sqlite_store).await, diff --git a/atuin/src/command/client/search.rs b/atuin/src/command/client/search.rs index 0e8e0205..456dc391 100644 --- a/atuin/src/command/client/search.rs +++ b/atuin/src/command/client/search.rs @@ -5,7 +5,9 @@ use eyre::Result; use atuin_client::{ database::Database, database::{current_context, OptFilters}, - history::History, + encryption, + history::{store::HistoryStore, History}, + record::sqlite_store::SqliteStore, settings::{FilterMode, KeymapMode, SearchMode, Settings}, }; @@ -109,7 +111,12 @@ pub struct Cmd { } impl Cmd { - pub async fn run(self, db: impl Database, settings: &mut Settings) -> Result<()> { + pub async fn run( + self, + db: impl Database, + settings: &mut Settings, + store: SqliteStore, + ) -> Result<()> { if (self.delete_it_all || self.delete) && self.limit.is_some() { // Because of how deletion is implemented, it will always delete all matches // and disregard the limit option. It is also not clear what deletion with a @@ -153,8 +160,13 @@ impl Cmd { value => value, }; + let encryption_key: [u8; 32] = encryption::load_key(settings)?.into(); + + let host_id = Settings::host_id().expect("failed to get host_id"); + let history_store = HistoryStore::new(store.clone(), host_id, encryption_key); + if self.interactive { - let item = interactive::history(&self.query, settings, db).await?; + let item = interactive::history(&self.query, settings, db, &history_store).await?; eprintln!("{}", item.escape_control()); } else { let list_mode = ListMode::from_flags(self.human, self.cmd_only); @@ -186,7 +198,13 @@ impl Cmd { while !entries.is_empty() { for entry in &entries { eprintln!("deleting {}", entry.id); - db.delete(entry.clone()).await?; + + if settings.sync.records { + let (id, _) = history_store.delete(entry.id.clone()).await?; + history_store.incremental_build(&db, &[id]).await?; + } else { + db.delete(entry.clone()).await?; + } } entries = diff --git a/atuin/src/command/client/search/interactive.rs b/atuin/src/command/client/search/interactive.rs index c838e873..209dc7f0 100644 --- a/atuin/src/command/client/search/interactive.rs +++ b/atuin/src/command/client/search/interactive.rs @@ -20,7 +20,7 @@ use unicode_width::UnicodeWidthStr; use atuin_client::{ database::{current_context, Database}, - history::{History, HistoryStats}, + history::{store::HistoryStore, History, HistoryStats}, settings::{ExitMode, FilterMode, KeymapMode, SearchMode, Settings}, }; @@ -769,6 +769,7 @@ pub async fn history( query: &[String], settings: &Settings, mut db: impl Database, + history_store: &HistoryStore, ) -> Result { let stdout = Stdout::new(settings.inline_height > 0)?; let backend = CrosstermBackend::new(stdout); @@ -857,7 +858,13 @@ pub async fn history( } let entry = results.remove(index); - db.delete(entry).await?; + + if settings.sync.records { + let (id, _) = history_store.delete(entry.id).await?; + history_store.incremental_build(&db, &[id]).await?; + } else { + db.delete(entry.clone()).await?; + } app.tab_index = 0; },