summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-07-22 17:55:46 +0300
committerLars Wirzenius <liw@liw.fi>2021-07-23 19:23:12 +0300
commitda4ac27a82029d562a9e9c48ce2a709692930cc1 (patch)
tree79fa7899e6c54e0ef9c21e838bebdbd6f8eebc89 /src
parent0d6ff366b09fbe37764863cc672741ba34dea56d (diff)
downloadobnam2-da4ac27a82029d562a9e9c48ce2a709692930cc1.tar.gz
refactor: use async for "obnam list-files"
Sponsored-by: author
Diffstat (limited to 'src')
-rw-r--r--src/client.rs29
-rw-r--r--src/cmd/list_files.rs14
2 files changed, 39 insertions, 4 deletions
diff --git a/src/client.rs b/src/client.rs
index 4ee3d3c..ca0104f 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -100,6 +100,35 @@ impl AsyncBackupClient {
pub async fn fetch_chunk(&self, chunk_id: &ChunkId) -> Result<DataChunk, ClientError> {
self.chunk_client.fetch_chunk(chunk_id).await
}
+
+ async fn fetch_generation_chunk(&self, gen_id: &str) -> Result<GenerationChunk, ClientError> {
+ let chunk_id = ChunkId::recreate(gen_id);
+ let chunk = self.fetch_chunk(&chunk_id).await?;
+ let gen = GenerationChunk::from_data_chunk(&chunk)?;
+ Ok(gen)
+ }
+
+ pub async fn fetch_generation(
+ &self,
+ gen_id: &str,
+ dbname: &Path,
+ ) -> Result<LocalGeneration, ClientError> {
+ let gen = self.fetch_generation_chunk(gen_id).await?;
+
+ // Fetch the SQLite file, storing it in the named file.
+ let mut dbfile = File::create(&dbname)
+ .map_err(|err| ClientError::FileCreate(dbname.to_path_buf(), err))?;
+ for id in gen.chunk_ids() {
+ let chunk = self.fetch_chunk(id).await?;
+ dbfile
+ .write_all(chunk.data())
+ .map_err(|err| ClientError::FileWrite(dbname.to_path_buf(), err))?;
+ }
+ info!("downloaded generation to {}", dbname.display());
+
+ let gen = LocalGeneration::open(dbname)?;
+ Ok(gen)
+ }
}
pub struct AsyncChunkClient {
diff --git a/src/cmd/list_files.rs b/src/cmd/list_files.rs
index c5191f7..723781b 100644
--- a/src/cmd/list_files.rs
+++ b/src/cmd/list_files.rs
@@ -1,10 +1,11 @@
use crate::backup_reason::Reason;
-use crate::client::BackupClient;
+use crate::client::AsyncBackupClient;
use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
use structopt::StructOpt;
use tempfile::NamedTempFile;
+use tokio::runtime::Runtime;
#[derive(Debug, StructOpt)]
pub struct ListFiles {
@@ -14,14 +15,19 @@ pub struct ListFiles {
impl ListFiles {
pub fn run(&self, config: &ClientConfig) -> Result<(), ObnamError> {
+ let rt = Runtime::new()?;
+ rt.block_on(self.run_async(config))
+ }
+
+ async fn run_async(&self, config: &ClientConfig) -> Result<(), ObnamError> {
let temp = NamedTempFile::new()?;
- let client = BackupClient::new(config)?;
+ let client = AsyncBackupClient::new(config)?;
- let genlist = client.list_generations()?;
+ let genlist = client.list_generations().await?;
let gen_id: String = genlist.resolve(&self.gen_id)?;
- let gen = client.fetch_generation(&gen_id, temp.path())?;
+ let gen = client.fetch_generation(&gen_id, temp.path()).await?;
for file in gen.files()?.iter()? {
let file = file?;
println!("{}", format_entry(&file.entry(), file.reason()));