refactor: move init_db to reth_db and add DatabaseEnv (#3450)

This commit is contained in:
joshieDo
2023-06-28 22:03:00 +01:00
committed by GitHub
parent 6e2fa845d8
commit a53af3a0f2
35 changed files with 234 additions and 175 deletions

View File

@ -87,3 +87,89 @@ pub use abstraction::*;
pub use reth_interfaces::db::DatabaseError;
pub use tables::*;
pub use utils::is_database_empty;
#[cfg(feature = "mdbx")]
use mdbx::{Env, EnvKind, WriteMap};
#[cfg(feature = "mdbx")]
/// Alias type for the database engine in use.
pub type DatabaseEnv = Env<WriteMap>;
/// Opens up an existing database or creates a new one at the specified path.
pub fn init_db<P: AsRef<std::path::Path>>(path: P) -> eyre::Result<DatabaseEnv> {
use crate::version::{check_db_version_file, create_db_version_file, DatabaseVersionError};
use eyre::WrapErr;
let rpath = path.as_ref();
if is_database_empty(rpath) {
std::fs::create_dir_all(rpath)
.wrap_err_with(|| format!("Could not create database directory {}", rpath.display()))?;
create_db_version_file(rpath)?;
} else {
match check_db_version_file(rpath) {
Ok(_) => (),
Err(DatabaseVersionError::MissingFile) => create_db_version_file(rpath)?,
Err(err) => return Err(err.into()),
}
}
#[cfg(feature = "mdbx")]
{
let db = Env::<WriteMap>::open(rpath, EnvKind::RW)?;
db.create_tables()?;
Ok(db)
}
#[cfg(not(feature = "mdbx"))]
{
unimplemented!();
}
}
#[cfg(test)]
mod tests {
use crate::{
init_db,
version::{db_version_file_path, DatabaseVersionError},
};
use assert_matches::assert_matches;
use tempfile::tempdir;
#[test]
fn db_version() {
let path = tempdir().unwrap();
// Database is empty
{
let db = init_db(&path);
assert_matches!(db, Ok(_));
}
// Database is not empty, current version is the same as in the file
{
let db = init_db(&path);
assert_matches!(db, Ok(_));
}
// Database is not empty, version file is malformed
{
std::fs::write(path.path().join(db_version_file_path(&path)), "invalid-version")
.unwrap();
let db = init_db(&path);
assert!(db.is_err());
assert_matches!(
db.unwrap_err().downcast_ref::<DatabaseVersionError>(),
Some(DatabaseVersionError::MalformedFile)
)
}
// Database is not empty, version file contains not matching version
{
std::fs::write(path.path().join(db_version_file_path(&path)), "0").unwrap();
let db = init_db(&path);
assert!(db.is_err());
assert_matches!(
db.unwrap_err().downcast_ref::<DatabaseVersionError>(),
Some(DatabaseVersionError::VersionMismatch { version: 0 })
)
}
}
}