Skip to content

Commit

Permalink
fix: doc export exports the latest entry at a given key (#1629)
Browse files Browse the repository at this point in the history
## Description

We currently only export via the latest key & the author id, but in the
CLI and console, we don't currently have a way of viewing other authors.

This needs to be fixed asap for demo purposes, and we should have a
longer discussion about how we expose the other peers' author ids to the
CLI and console: #1628

## Change checklist

- [x] Self-review.
- [x] Documentation updates if relevant.
  • Loading branch information
ramfox authored Oct 12, 2023
1 parent 792c756 commit b815576
Showing 1 changed file with 32 additions and 18 deletions.
50 changes: 32 additions & 18 deletions iroh/src/commands/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,17 @@ pub enum DocCommands {
#[clap(short, long)]
in_place: bool,
},
/// Export data from a document
/// Export the most recent data for a key from a document
Export {
/// Document to operate on.
///
/// Required unless the document is set through the IROH_DOC environment variable.
/// Within the Iroh console, the active document can also be set with `doc switch`.
#[clap(short, long)]
doc: Option<NamespaceId>,
/// Author of the entry.
///
/// Required unless the author is set through the IROH_AUTHOR environment variable.
/// Within the Iroh console, the active author can also be set with `author switch`.
#[clap(short, long)]
author: Option<AuthorId>,
/// Key to the entry (parsed as UTF-8 string)
///
/// When just the key is present, will export the latest entry for that key.
key: String,
/// Path to export to
#[clap(short, long)]
Expand Down Expand Up @@ -423,21 +419,19 @@ impl DocCommands {
import_coordinator(doc, author, root_prefix, prefix, stream, size, files).await?;
println!("Success! ({})", HumanDuration(start.elapsed()));
}
Self::Export {
doc,
author,
key,
out,
} => {
Self::Export { doc, key, out } => {
let doc = get_doc(iroh, env, doc).await?;
let author = env.author(author)?;
let key_str = key.clone();
let key = key.as_bytes().to_vec();
let path: PathBuf = canonicalize_path(&out)?;
let entry = doc
.get_one(author, key)
.await?
.ok_or_else(|| anyhow!("<could not find entry {key_str}>"))?;
let stream = doc.get_many(GetFilter::Key(key)).await?;
let entry = match get_latest(stream).await? {
None => {
println!("<unable to find entry for key {key_str}>");
return Ok(());
}
Some(e) => e,
};
match doc.read(&entry).await {
Ok(mut content) => {
if let Some(dir) = path.parent() {
Expand Down Expand Up @@ -857,3 +851,23 @@ impl ImportProgressBar {
self.mp.clear().ok();
}
}

/// Get the latest entry for a key. If `None`, then an entry of the given key
/// could not be found.
async fn get_latest(stream: impl Stream<Item = Result<Entry>>) -> Result<Option<Entry>> {
let entry = stream
.try_fold(None, |acc: Option<Entry>, cur: Entry| async move {
match acc {
None => Ok(Some(cur)),
Some(prev) => {
if cur.timestamp() > prev.timestamp() {
Ok(Some(cur))
} else {
Ok(Some(prev))
}
}
}
})
.await?;
Ok(entry)
}

0 comments on commit b815576

Please sign in to comment.