use crate::{ error::{mdbx_result, Result}, transaction::TransactionKind, Environment, Transaction, }; use ffi::MDBX_db_flags_t; use std::{ffi::CString, ptr}; /// A handle to an individual database in an environment. /// /// A database handle denotes the name and parameters of a database in an environment. #[derive(Debug)] pub struct Database { dbi: ffi::MDBX_dbi, /// The environment that this database belongs to keeps it alive as long as the database /// instance exists. _env: Option, } impl Database { /// Opens a new database handle in the given transaction. /// /// Prefer using `Environment::open_db`, `Environment::create_db`, `TransactionExt::open_db`, /// or `RwTransaction::create_db`. pub(crate) fn new( txn: &Transaction, name: Option<&str>, flags: MDBX_db_flags_t, ) -> Result { let c_name = name.map(|n| CString::new(n).unwrap()); let name_ptr = if let Some(c_name) = &c_name { c_name.as_ptr() } else { ptr::null() }; let mut dbi: ffi::MDBX_dbi = 0; txn.txn_execute(|txn_ptr| { mdbx_result(unsafe { ffi::mdbx_dbi_open(txn_ptr, name_ptr, flags, &mut dbi) }) })??; Ok(Self::new_from_ptr(dbi, txn.env().clone())) } pub(crate) const fn new_from_ptr(dbi: ffi::MDBX_dbi, env: Environment) -> Self { Self { dbi, _env: Some(env) } } /// Opens the freelist database with DBI `0`. pub const fn freelist_db() -> Self { Self { dbi: 0, _env: None } } /// Returns the underlying MDBX database handle. /// /// The caller **must** ensure that the handle is not used after the lifetime of the /// environment, or after the database has been closed. pub const fn dbi(&self) -> ffi::MDBX_dbi { self.dbi } } unsafe impl Send for Database {} unsafe impl Sync for Database {}