use crate::{
Environment, Transaction, TransactionKind,
error::{MdbxResult, mdbx_result},
};
use ffi::MDBX_db_flags_t;
use std::{ffi::CStr, ptr};
#[derive(Debug)]
pub struct Database {
dbi: ffi::MDBX_dbi,
_env: Option<Environment>,
}
impl Database {
pub(crate) fn new<K: TransactionKind>(
txn: &Transaction<K>,
name: Option<&str>,
flags: MDBX_db_flags_t,
) -> MdbxResult<Self> {
let mut c_name_buf = smallvec::SmallVec::<[u8; 32]>::new();
let c_name = name.map(|n| {
c_name_buf.extend_from_slice(n.as_bytes());
c_name_buf.push(0);
CStr::from_bytes_with_nul(&c_name_buf).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) }
}
pub const fn freelist_db() -> Self {
Self { dbi: 0, _env: None }
}
pub const fn dbi(&self) -> ffi::MDBX_dbi {
self.dbi
}
}
unsafe impl Send for Database {}
unsafe impl Sync for Database {}