From 4b54e053dfd1bd950e86ffad9b4155a47806d8f1 Mon Sep 17 00:00:00 2001 From: Zdenek Crha Date: Thu, 18 Jan 2024 17:57:53 +0100 Subject: convert_db: prevent conversion between same input/output engine Use optional DB open overrides for both input and output database. Duplicating the same override flag for input/output would result in too many, too long flags. It would be too costly for very rare edge-case where converting between same DB engine, just with different flags. Because overrides flags for different engines are disjoint and we are preventing conversion between same input/ouput DB engine, we can have only one set. The override flag will be passed either to input or output, based on engine type it belongs to. It will never be passed to both of them and cause unwelcome surprise to user. --- src/db/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/db') diff --git a/src/db/lib.rs b/src/db/lib.rs index fe44b01e..427140f9 100644 --- a/src/db/lib.rs +++ b/src/db/lib.rs @@ -171,6 +171,53 @@ impl Db { } } +/// List of supported database engine types +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Engine { + #[cfg(feature = "lmdb")] + Lmdb, + + #[cfg(feature = "sqlite")] + Sqlite, + + #[cfg(feature = "sled")] + Sled, +} + +impl std::fmt::Display for Engine { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + #[cfg(feature = "lmdb")] + Self::Lmdb => fmt.write_str("lmdb"), + + #[cfg(feature = "sqlite")] + Self::Sqlite => fmt.write_str("sqlite"), + + #[cfg(feature = "sled")] + Self::Sled => fmt.write_str("sled"), + } + } +} + +impl std::str::FromStr for Engine { + type Err = Error; + + fn from_str(text: &str) -> Result { + match text { + #[cfg(feature = "lmdb")] + "lmdb" | "heed" => Ok(Self::Lmdb), + + #[cfg(feature = "sqlite")] + "sqlite" | "sqlite3" | "rusqlite" => Ok(Self::Sqlite), + + #[cfg(feature = "sled")] + "sled" => Ok(Self::Sled), + + kind => Err(Error(format!("Invalid DB engine: {}", kind).into())), + } + } +} + #[allow(clippy::len_without_is_empty)] impl Tree { #[inline] -- cgit v1.2.3 From 0eef8a69f0006de305281dd374cc63e7a46e4b80 Mon Sep 17 00:00:00 2001 From: Zdenek Crha Date: Mon, 22 Jan 2024 20:38:14 +0100 Subject: make all garage_db::Engine variants un-conditional Having all Engine enum variants conditional causes compilation errors when *none* of the DB engine features is enabled. This is not an issue for full garage build, but affects crates that use garage_db as dependency. Change all variants to be present at all times. It solves compilation errors and also allows us to better differentiate between invalid DB engine name and engine with support not compiled in current binary. --- src/db/lib.rs | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'src/db') diff --git a/src/db/lib.rs b/src/db/lib.rs index 427140f9..eef3e177 100644 --- a/src/db/lib.rs +++ b/src/db/lib.rs @@ -172,47 +172,42 @@ impl Db { } /// List of supported database engine types +/// +/// The `enum` holds list of *all* database engines that are are be supported by crate, no matter +/// if relevant feature is enabled or not. It allows us to distinguish between invalid engine +/// and valid engine, whose support is not enabled via feature flag. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Engine { - #[cfg(feature = "lmdb")] Lmdb, - - #[cfg(feature = "sqlite")] Sqlite, - - #[cfg(feature = "sled")] Sled, } -impl std::fmt::Display for Engine { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { +impl Engine { + /// Return variant name as static `&str` + pub fn as_str(&self) -> &'static str { match self { - #[cfg(feature = "lmdb")] - Self::Lmdb => fmt.write_str("lmdb"), - - #[cfg(feature = "sqlite")] - Self::Sqlite => fmt.write_str("sqlite"), - - #[cfg(feature = "sled")] - Self::Sled => fmt.write_str("sled"), + Self::Lmdb => "lmdb", + Self::Sqlite => "sqlite", + Self::Sled => "sled", } } } +impl std::fmt::Display for Engine { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + self.as_str().fmt(fmt) + } +} + impl std::str::FromStr for Engine { type Err = Error; fn from_str(text: &str) -> Result { match text { - #[cfg(feature = "lmdb")] "lmdb" | "heed" => Ok(Self::Lmdb), - - #[cfg(feature = "sqlite")] "sqlite" | "sqlite3" | "rusqlite" => Ok(Self::Sqlite), - - #[cfg(feature = "sled")] "sled" => Ok(Self::Sled), - kind => Err(Error(format!("Invalid DB engine: {}", kind).into())), } } -- cgit v1.2.3