use leveldb_sys::*;
use crate::iter::OwnedIterator;
use crate::options::Options;
use crate::options::ReadOptions;
use crate::string::String as LevelDbString;
use std::ffi::CString;
#[derive(Debug)]
pub struct Db {
ptr: *mut leveldb_t,
#[allow(dead_code)]
options: Options,
}
impl Db {
pub fn open(path: impl Into<Vec<u8>>, options: Options) -> Result<Self, LevelDbString> {
let path = CString::new(path).expect("path had interior NUL");
let mut err_ptr = std::ptr::null_mut();
let ptr = unsafe {
let ptr = leveldb_open(options.0, path.as_ptr(), &mut err_ptr);
let err = LevelDbString::try_from_ptr(err_ptr);
if let Some(err) = err {
return Err(err);
}
ptr
};
assert!(!ptr.is_null());
Ok(Db { ptr, options })
}
pub fn get(
&mut self,
options: &ReadOptions,
key: &[u8],
) -> Result<Option<LevelDbString>, LevelDbString> {
let mut value_len = 0;
let mut err_ptr = std::ptr::null_mut();
let value_ptr = unsafe {
leveldb_get(
self.ptr,
options.0,
key.as_ptr().cast(),
key.len(),
&mut value_len,
&mut err_ptr,
)
};
let value = unsafe { LevelDbString::try_from_ptr_len(value_ptr, value_len) };
let err = unsafe { LevelDbString::try_from_ptr(err_ptr) };
if let Some(err) = err {
return Err(err);
}
Ok(value)
}
pub fn iter_owned(&mut self, options: &ReadOptions) -> OwnedIterator {
unsafe {
let ptr = leveldb_create_iterator(self.ptr, options.0);
OwnedIterator::from_parts(ptr, self)
}
}
}
impl Drop for Db {
fn drop(&mut self) {
unsafe {
leveldb_close(self.ptr);
}
}
}