blockchain: create crate::open(), OpenTables::create_tables()

This commit is contained in:
hinto.janai 2024-06-17 16:08:59 -04:00
parent ed7571fa33
commit 5841841674
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
4 changed files with 73 additions and 2 deletions

View file

@ -45,7 +45,7 @@ Failing to uphold these invariants may cause panics.
# Examples
The below is an example of using `cuprate_blockchain`
lowest API, i.e. using a mix of this crate and `cuprate_database`'s traits directly -
this is not recommended.
**this is NOT recommended.**
For examples of the higher-level APIs, see:
- [`ops`]

View file

@ -1,8 +1,61 @@
//! General free functions (related to the database).
//---------------------------------------------------------------------------------------------------- Import
use cuprate_database::{ConcreteEnv, Env, EnvInner, InitError, RuntimeError, TxRw};
use crate::{config::Config, open_tables::OpenTables};
//---------------------------------------------------------------------------------------------------- Free functions
/// TODO
///
/// # Errors
/// TODO
pub fn open(config: Config) -> Result<ConcreteEnv, InitError> {
// Attempt to open the database environment.
let env = <ConcreteEnv as Env>::open(config.db_config)?;
/// Convert runtime errors to init errors.
///
/// INVARIANT:
/// `cuprate_database`'s functions mostly return the former
/// so we must convert them. We have knowledge of which errors
/// makes sense in this functions context so we panic on
/// unexpected ones.
fn runtime_to_init_error(runtime: RuntimeError) -> InitError {
match runtime {
RuntimeError::Io(io_error) => io_error.into(),
// These errors shouldn't be happening here.
RuntimeError::KeyExists
| RuntimeError::KeyNotFound
| RuntimeError::ResizeNeeded
| RuntimeError::TableNotFound => unreachable!(),
}
}
// INVARIANT: We must ensure that all tables are created,
// `cuprate_database` has no way of knowing _which_ tables
// we want since it is agnostic, so we are responsible for this.
{
let env_inner = env.env_inner();
let tx_rw = env_inner.tx_rw();
let tx_rw = match tx_rw {
Ok(tx_rw) => tx_rw,
Err(e) => return Err(runtime_to_init_error(e)),
};
// Create all tables.
if let Err(e) = OpenTables::create_tables(&env_inner, &tx_rw) {
return Err(runtime_to_init_error(e));
};
if let Err(e) = tx_rw.commit() {
return Err(runtime_to_init_error(e));
}
}
Ok(env)
}
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]

View file

@ -114,7 +114,9 @@ pub use constants::{DATABASE_CORRUPT_MSG, DATABASE_VERSION};
mod open_tables;
pub use open_tables::OpenTables;
pub mod free;
mod free;
pub use free::open;
pub mod ops;
pub mod tables;
pub mod types;

View file

@ -41,6 +41,7 @@ macro_rules! call_fn_on_all_tables_or_early_return {
))
}};
}
pub(crate) use call_fn_on_all_tables_or_early_return;
//---------------------------------------------------------------------------------------------------- OpenTables
/// TODO
@ -61,6 +62,12 @@ where
/// # Errors
/// TODO
fn open_tables_mut(&'env self, tx_rw: &Rw) -> Result<impl TablesMut, RuntimeError>;
/// TODO
///
/// # Errors
/// TODO
fn create_tables(&'env self, tx_rw: &Rw) -> Result<(), RuntimeError>;
}
impl<'env, Ei, Ro, Rw> OpenTables<'env, Ro, Rw> for Ei
@ -80,6 +87,15 @@ where
Self::open_db_rw(self, tx_rw)
}
}
fn create_tables(&'env self, tx_rw: &Rw) -> Result<(), RuntimeError> {
match call_fn_on_all_tables_or_early_return! {
Self::create_db(self, tx_rw)
} {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
}
//---------------------------------------------------------------------------------------------------- Tests