diff options
author | Lars Wirzenius <liw@liw.fi> | 2022-03-22 17:10:02 +0000 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2022-03-22 17:10:02 +0000 |
commit | 4a9b26903d48d622f7f2a01eb54eec88e92da868 (patch) | |
tree | 6d1a5f4fa835cd217d256ac3cdd5baec5902a2af /src/genmeta.rs | |
parent | 7ae1f33ad0cd0df227e83997268ce2f3540db8d7 (diff) | |
parent | 018fcd28c8dbf84d34cc370496139f678664ca8f (diff) | |
download | obnam2-4a9b26903d48d622f7f2a01eb54eec88e92da868.tar.gz |
Merge branch 'liw/schema-refactor' into 'main'
add backup database schema to evolove; break server database
Closes #194 and #192
See merge request obnam/obnam!222
Diffstat (limited to 'src/genmeta.rs')
-rw-r--r-- | src/genmeta.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/genmeta.rs b/src/genmeta.rs new file mode 100644 index 0000000..2ce4c4c --- /dev/null +++ b/src/genmeta.rs @@ -0,0 +1,57 @@ +//! Backup generations metadata. + +use crate::schema::{SchemaVersion, VersionComponent}; +use serde::Serialize; +use std::collections::HashMap; + +/// Metadata about the local generation. +#[derive(Debug, Serialize)] +pub struct GenerationMeta { + schema_version: SchemaVersion, + extras: HashMap<String, String>, +} + +impl GenerationMeta { + /// Create from a hash map. + pub fn from(mut map: HashMap<String, String>) -> Result<Self, GenerationMetaError> { + let major: VersionComponent = metaint(&mut map, "schema_version_major")?; + let minor: VersionComponent = metaint(&mut map, "schema_version_minor")?; + Ok(Self { + schema_version: SchemaVersion::new(major, minor), + extras: map, + }) + } + + /// Return schema version of local generation. + pub fn schema_version(&self) -> SchemaVersion { + self.schema_version + } +} + +fn metastr(map: &mut HashMap<String, String>, key: &str) -> Result<String, GenerationMetaError> { + if let Some(v) = map.remove(key) { + Ok(v) + } else { + Err(GenerationMetaError::NoMetaKey(key.to_string())) + } +} + +fn metaint(map: &mut HashMap<String, String>, key: &str) -> Result<u32, GenerationMetaError> { + let v = metastr(map, key)?; + let v = v + .parse() + .map_err(|err| GenerationMetaError::BadMetaInteger(key.to_string(), err))?; + Ok(v) +} + +/// Possible errors from getting generation metadata. +#[derive(Debug, thiserror::Error)] +pub enum GenerationMetaError { + /// Missing from from 'meta' table. + #[error("Generation 'meta' table does not have a row {0}")] + NoMetaKey(String), + + /// Bad data in 'meta' table. + #[error("Generation 'meta' row {0} has badly formed integer: {1}")] + BadMetaInteger(String, std::num::ParseIntError), +} |