use super::Database;
use super::slice::Slice;
use super::bytes::Bytes;
use super::error::Error;
use crate::binding::*;
use crate::options::{ReadOptions, WriteOptions, c_readoptions, c_writeoptions};
use libc::{c_char, size_t};
use std::ptr;
pub trait KV {
fn get<'a>(
&self,
options: ReadOptions<'a>,
key: Slice,
) -> Result<Option<Slice<'static>>, Error>;
fn put(&self, options: WriteOptions, key: Slice, value: Slice) -> Result<(), Error>;
fn delete(&self, options: WriteOptions, key: Slice) -> Result<(), Error>;
}
impl KV for Database {
fn put(&self, options: WriteOptions, key: Slice, value: Slice) -> Result<(), Error> {
unsafe {
let k = key.as_bytes();
let v = value.as_bytes();
let mut error = ptr::null_mut();
let c_writeoptions = c_writeoptions(options);
leveldb_put(
self.database.ptr,
c_writeoptions,
k.as_ptr() as *mut c_char,
k.len() as size_t,
v.as_ptr() as *mut c_char,
v.len() as size_t,
&mut error,
);
leveldb_writeoptions_destroy(c_writeoptions);
if error.is_null() {
Ok(())
} else {
Err(Error::new_from_char(error))
}
}
}
fn delete(&self, options: WriteOptions, key: Slice) -> Result<(), Error> {
unsafe {
let k = key.as_bytes();
let mut error = ptr::null_mut();
let c_writeoptions = c_writeoptions(options);
leveldb_delete(
self.database.ptr,
c_writeoptions,
k.as_ptr() as *mut c_char,
k.len() as size_t,
&mut error,
);
leveldb_writeoptions_destroy(c_writeoptions);
if error.is_null() {
Ok(())
} else {
Err(Error::new_from_char(error))
}
}
}
fn get<'a>(
&self,
options: ReadOptions<'a>,
key: Slice,
) -> Result<Option<Slice<'static>>, Error> {
unsafe {
let k = key.as_bytes();
let mut error = ptr::null_mut();
let mut length: size_t = 0;
let c_readoptions = c_readoptions(&options);
let result = leveldb_get(
self.database.ptr,
c_readoptions,
k.as_ptr() as *mut c_char,
k.len() as size_t,
&mut length,
&mut error,
);
leveldb_readoptions_destroy(c_readoptions);
if error.is_null() {
if result.is_null() {
Ok(None)
} else if let Some(bytes) = Bytes::from_raw(result as *mut u8, length) {
Ok(Some(bytes.into()))
} else {
Ok(None)
}
} else {
Err(Error::new_from_char(error))
}
}
}
}