diff options
author | Alexander Batischev <eual.jp@gmail.com> | 2021-04-25 18:29:19 +0300 |
---|---|---|
committer | Alexander Batischev <eual.jp@gmail.com> | 2021-04-26 15:00:05 +0300 |
commit | 36c89315fad651b3b8ce1f8e25310db3ea668fae (patch) | |
tree | 64f15f87468b7eecf41b59b0fbf2f74369ce640b /src/generation.rs | |
parent | 80aaff3f70f790141fbc8caa8a2f4830cd5e3fee (diff) | |
download | obnam2-36c89315fad651b3b8ce1f8e25310db3ea668fae.tar.gz |
Expose fallibility of individual SQL results
`LocalGeneration::sql::files()` runs an SQL query, iterates over the
results and collects the rows into a `Vec`. This can fail at any step:
the query might fail to run, or one of the rows might fail to be fetched
or processed.
Right now, we lump all those failures into a `Result` that wraps the
whole return value. This is only possible because we process each row
before returning. Once `Vec` is replaced by an iterator, we won't have
that luxury anymore, so we now wrap each individual element into its own
`Result` (as well as wrapping the whole vector into a `Result` of its
own).
Diffstat (limited to 'src/generation.rs')
-rw-r--r-- | src/generation.rs | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/src/generation.rs b/src/generation.rs index 1d0ee52..a780203 100644 --- a/src/generation.rs +++ b/src/generation.rs @@ -196,7 +196,7 @@ impl LocalGeneration { sql::file_count(&self.conn) } - pub fn files(&self) -> LocalGenerationResult<Vec<BackedUpFile>> { + pub fn files(&self) -> LocalGenerationResult<Vec<LocalGenerationResult<BackedUpFile>>> { sql::files(&self.conn) } @@ -289,14 +289,22 @@ mod sql { Ok(count) } - pub fn files(conn: &Connection) -> LocalGenerationResult<Vec<BackedUpFile>> { + pub fn files( + conn: &Connection, + ) -> LocalGenerationResult<Vec<LocalGenerationResult<BackedUpFile>>> { let mut stmt = conn.prepare("SELECT * FROM files")?; let iter = stmt.query_map(params![], |row| row_to_entry(row))?; - let mut files = vec![]; + let mut files: Vec<LocalGenerationResult<BackedUpFile>> = vec![]; for x in iter { - let (fileno, json, reason) = x?; - let entry = serde_json::from_str(&json)?; - files.push(BackedUpFile::new(fileno, entry, &reason)); + match x { + Ok((fileno, json, reason)) => { + let result = serde_json::from_str(&json) + .map(|entry| BackedUpFile::new(fileno, entry, &reason)) + .map_err(|e| e.into()); + files.push(result) + } + Err(e) => files.push(Err(e.into())), + } } Ok(files) } |