|
|
|
@ -22,6 +22,7 @@ use std::ops::Deref; |
|
|
|
|
use std::path::Path; |
|
|
|
|
use std::slice; |
|
|
|
|
use std::str::from_utf8; |
|
|
|
|
use std::fmt; |
|
|
|
|
|
|
|
|
|
use self::libc::size_t; |
|
|
|
|
|
|
|
|
@ -62,6 +63,35 @@ pub enum Direction { |
|
|
|
|
|
|
|
|
|
pub type KVBytes = (Box<[u8]>, Box<[u8]>); |
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)] |
|
|
|
|
pub struct Error { |
|
|
|
|
message: String, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Error { |
|
|
|
|
fn new(message: String) -> Error { |
|
|
|
|
Error { |
|
|
|
|
message: message, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn to_string(self) -> String { |
|
|
|
|
self.into() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl From<Error> for String { |
|
|
|
|
fn from(e: Error) -> String { |
|
|
|
|
e.message |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl fmt::Display for Error { |
|
|
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { |
|
|
|
|
self.message.fmt(formatter) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Iterator for DBIterator { |
|
|
|
|
type Item = KVBytes; |
|
|
|
|
|
|
|
|
@ -163,7 +193,7 @@ impl DBIterator { |
|
|
|
|
cf_handle: DBCFHandle, |
|
|
|
|
readopts: &ReadOptions, |
|
|
|
|
mode: IteratorMode) |
|
|
|
|
-> Result<DBIterator, String> { |
|
|
|
|
-> Result<DBIterator, Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let iterator = |
|
|
|
|
rocksdb_ffi::rocksdb_create_iterator_cf(db.inner, |
|
|
|
@ -211,14 +241,14 @@ impl<'a> Snapshot<'a> { |
|
|
|
|
pub fn iterator_cf(&self, |
|
|
|
|
cf_handle: DBCFHandle, |
|
|
|
|
mode: IteratorMode) |
|
|
|
|
-> Result<DBIterator, String> { |
|
|
|
|
-> Result<DBIterator, Error> { |
|
|
|
|
let mut readopts = ReadOptions::default(); |
|
|
|
|
readopts.set_snapshot(self); |
|
|
|
|
DBIterator::new_cf(self.db, cf_handle, &readopts, mode) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn get(&self, key: &[u8]) -> Result<Option<DBVector>, String> { |
|
|
|
|
pub fn get(&self, key: &[u8]) -> Result<Option<DBVector>, Error> { |
|
|
|
|
let mut readopts = ReadOptions::default(); |
|
|
|
|
readopts.set_snapshot(self); |
|
|
|
|
self.db.get_opt(key, &readopts) |
|
|
|
@ -227,7 +257,7 @@ impl<'a> Snapshot<'a> { |
|
|
|
|
pub fn get_cf(&self, |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8]) |
|
|
|
|
-> Result<Option<DBVector>, String> { |
|
|
|
|
-> Result<Option<DBVector>, Error> { |
|
|
|
|
let mut readopts = ReadOptions::default(); |
|
|
|
|
readopts.set_snapshot(self); |
|
|
|
|
self.db.get_cf_opt(cf, key, &readopts) |
|
|
|
@ -244,32 +274,32 @@ impl<'a> Drop for Snapshot<'a> { |
|
|
|
|
|
|
|
|
|
// This is for the DB and write batches to share the same API
|
|
|
|
|
pub trait Writable { |
|
|
|
|
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String>; |
|
|
|
|
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error>; |
|
|
|
|
fn put_cf(&self, |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8]) |
|
|
|
|
-> Result<(), String>; |
|
|
|
|
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String>; |
|
|
|
|
-> Result<(), Error>; |
|
|
|
|
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error>; |
|
|
|
|
fn merge_cf(&self, |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8]) |
|
|
|
|
-> Result<(), String>; |
|
|
|
|
fn delete(&self, key: &[u8]) -> Result<(), String>; |
|
|
|
|
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String>; |
|
|
|
|
-> Result<(), Error>; |
|
|
|
|
fn delete(&self, key: &[u8]) -> Result<(), Error>; |
|
|
|
|
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), Error>; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl DB { |
|
|
|
|
/// Open a database with default options
|
|
|
|
|
pub fn open_default(path: &str) -> Result<DB, String> { |
|
|
|
|
pub fn open_default(path: &str) -> Result<DB, Error> { |
|
|
|
|
let mut opts = Options::default(); |
|
|
|
|
opts.create_if_missing(true); |
|
|
|
|
DB::open(&opts, path) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Open the database with specified options
|
|
|
|
|
pub fn open(opts: &Options, path: &str) -> Result<DB, String> { |
|
|
|
|
pub fn open(opts: &Options, path: &str) -> Result<DB, Error> { |
|
|
|
|
DB::open_cf(opts, path, &[]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -283,20 +313,20 @@ impl DB { |
|
|
|
|
pub fn open_cf(opts: &Options, |
|
|
|
|
path: &str, |
|
|
|
|
cfs: &[&str]) |
|
|
|
|
-> Result<DB, String> { |
|
|
|
|
-> Result<DB, Error> { |
|
|
|
|
let cpath = match CString::new(path.as_bytes()) { |
|
|
|
|
Ok(c) => c, |
|
|
|
|
Err(_) => { |
|
|
|
|
return Err("Failed to convert path to CString when opening \ |
|
|
|
|
return Err(Error::new("Failed to convert path to CString when opening \ |
|
|
|
|
rocksdb" |
|
|
|
|
.to_string()) |
|
|
|
|
.to_string())) |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
let cpath_ptr = cpath.as_ptr(); |
|
|
|
|
|
|
|
|
|
let ospath = Path::new(path); |
|
|
|
|
if let Err(e) = fs::create_dir_all(&ospath) { |
|
|
|
|
return Err(format!("Failed to create rocksdb directory: {:?}", e)) |
|
|
|
|
return Err(Error::new(format!("Failed to create rocksdb directory: {:?}", e))) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
@ -355,8 +385,8 @@ impl DB { |
|
|
|
|
|
|
|
|
|
for handle in &cfhandles { |
|
|
|
|
if handle.is_null() { |
|
|
|
|
return Err("Received null column family handle from DB." |
|
|
|
|
.to_string()); |
|
|
|
|
return Err(Error::new("Received null column family handle from DB." |
|
|
|
|
.to_string())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -366,10 +396,10 @@ impl DB { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
if db.is_null() { |
|
|
|
|
return Err("Could not initialize database.".to_string()); |
|
|
|
|
return Err(Error::new("Could not initialize database.".to_string())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Ok(DB { |
|
|
|
@ -378,7 +408,7 @@ impl DB { |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn destroy(opts: &Options, path: &str) -> Result<(), String> { |
|
|
|
|
pub fn destroy(opts: &Options, path: &str) -> Result<(), Error> { |
|
|
|
|
let cpath = CString::new(path.as_bytes()).unwrap(); |
|
|
|
|
let cpath_ptr = cpath.as_ptr(); |
|
|
|
|
|
|
|
|
@ -390,12 +420,12 @@ impl DB { |
|
|
|
|
err_ptr); |
|
|
|
|
} |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn repair(opts: Options, path: &str) -> Result<(), String> { |
|
|
|
|
pub fn repair(opts: Options, path: &str) -> Result<(), Error> { |
|
|
|
|
let cpath = CString::new(path.as_bytes()).unwrap(); |
|
|
|
|
let cpath_ptr = cpath.as_ptr(); |
|
|
|
|
|
|
|
|
@ -407,7 +437,7 @@ impl DB { |
|
|
|
|
err_ptr); |
|
|
|
|
} |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -415,7 +445,7 @@ impl DB { |
|
|
|
|
pub fn write_opt(&self, |
|
|
|
|
batch: WriteBatch, |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
|
unsafe { |
|
|
|
@ -425,16 +455,16 @@ impl DB { |
|
|
|
|
err_ptr); |
|
|
|
|
} |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn write(&self, batch: WriteBatch) -> Result<(), String> { |
|
|
|
|
pub fn write(&self, batch: WriteBatch) -> Result<(), Error> { |
|
|
|
|
self.write_opt(batch, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn write_withou_wal(&self, batch: WriteBatch) -> Result<(), String> { |
|
|
|
|
pub fn write_withou_wal(&self, batch: WriteBatch) -> Result<(), Error> { |
|
|
|
|
let mut wo = WriteOptions::new(); |
|
|
|
|
wo.disable_wal(true); |
|
|
|
|
self.write_opt(batch, &wo) |
|
|
|
@ -443,13 +473,13 @@ impl DB { |
|
|
|
|
pub fn get_opt(&self, |
|
|
|
|
key: &[u8], |
|
|
|
|
readopts: &ReadOptions) |
|
|
|
|
-> Result<Option<DBVector>, String> { |
|
|
|
|
-> Result<Option<DBVector>, Error> { |
|
|
|
|
if readopts.inner.is_null() { |
|
|
|
|
return Err("Unable to create rocksdb read options. This is a \ |
|
|
|
|
return Err(Error::new("Unable to create rocksdb read options. This is a \ |
|
|
|
|
fairly trivial call, and its failure may be \ |
|
|
|
|
indicative of a mis-compiled or mis-loaded rocksdb \ |
|
|
|
|
library." |
|
|
|
|
.to_string()); |
|
|
|
|
.to_string())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsafe { |
|
|
|
@ -465,7 +495,7 @@ impl DB { |
|
|
|
|
val_len_ptr, |
|
|
|
|
err_ptr) as *mut u8; |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
if val.is_null() { |
|
|
|
|
Ok(None) |
|
|
|
@ -476,7 +506,7 @@ impl DB { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Return the bytes associated with a key value
|
|
|
|
|
pub fn get(&self, key: &[u8]) -> Result<Option<DBVector>, String> { |
|
|
|
|
pub fn get(&self, key: &[u8]) -> Result<Option<DBVector>, Error> { |
|
|
|
|
self.get_opt(key, &ReadOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -484,13 +514,13 @@ impl DB { |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
readopts: &ReadOptions) |
|
|
|
|
-> Result<Option<DBVector>, String> { |
|
|
|
|
-> Result<Option<DBVector>, Error> { |
|
|
|
|
if readopts.inner.is_null() { |
|
|
|
|
return Err("Unable to create rocksdb read options. This is a \ |
|
|
|
|
return Err(Error::new("Unable to create rocksdb read options. This is a \ |
|
|
|
|
fairly trivial call, and its failure may be \ |
|
|
|
|
indicative of a mis-compiled or mis-loaded rocksdb \ |
|
|
|
|
library." |
|
|
|
|
.to_string()); |
|
|
|
|
.to_string())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsafe { |
|
|
|
@ -507,7 +537,7 @@ impl DB { |
|
|
|
|
val_len_ptr, |
|
|
|
|
err_ptr) as *mut u8; |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
if val.is_null() { |
|
|
|
|
Ok(None) |
|
|
|
@ -520,20 +550,20 @@ impl DB { |
|
|
|
|
pub fn get_cf(&self, |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8]) |
|
|
|
|
-> Result<Option<DBVector>, String> { |
|
|
|
|
-> Result<Option<DBVector>, Error> { |
|
|
|
|
self.get_cf_opt(cf, key, &ReadOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn create_cf(&mut self, |
|
|
|
|
name: &str, |
|
|
|
|
opts: &Options) |
|
|
|
|
-> Result<DBCFHandle, String> { |
|
|
|
|
-> Result<DBCFHandle, Error> { |
|
|
|
|
let cname = match CString::new(name.as_bytes()) { |
|
|
|
|
Ok(c) => c, |
|
|
|
|
Err(_) => { |
|
|
|
|
return Err("Failed to convert path to CString when opening \ |
|
|
|
|
return Err(Error::new("Failed to convert path to CString when opening \ |
|
|
|
|
rocksdb" |
|
|
|
|
.to_string()) |
|
|
|
|
.to_string())) |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
let cname_ptr = cname.as_ptr(); |
|
|
|
@ -549,15 +579,15 @@ impl DB { |
|
|
|
|
cf_handler |
|
|
|
|
}; |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(cf_handler) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn drop_cf(&mut self, name: &str) -> Result<(), String> { |
|
|
|
|
pub fn drop_cf(&mut self, name: &str) -> Result<(), Error> { |
|
|
|
|
let cf = self.cfs.get(name); |
|
|
|
|
if cf.is_none() { |
|
|
|
|
return Err(format!("Invalid column family: {}", name).to_string()); |
|
|
|
|
return Err(Error::new(format!("Invalid column family: {}", name).to_string())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
@ -568,7 +598,7 @@ impl DB { |
|
|
|
|
err_ptr); |
|
|
|
|
} |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
@ -587,7 +617,7 @@ impl DB { |
|
|
|
|
pub fn iterator_cf(&self, |
|
|
|
|
cf_handle: DBCFHandle, |
|
|
|
|
mode: IteratorMode) |
|
|
|
|
-> Result<DBIterator, String> { |
|
|
|
|
-> Result<DBIterator, Error> { |
|
|
|
|
let opts = ReadOptions::default(); |
|
|
|
|
DBIterator::new_cf(self, cf_handle, &opts, mode) |
|
|
|
|
} |
|
|
|
@ -600,7 +630,7 @@ impl DB { |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8], |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
@ -612,7 +642,7 @@ impl DB { |
|
|
|
|
value.len() as size_t, |
|
|
|
|
err_ptr); |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -623,7 +653,7 @@ impl DB { |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8], |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
@ -636,7 +666,7 @@ impl DB { |
|
|
|
|
value.len() as size_t, |
|
|
|
|
err_ptr); |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -645,7 +675,7 @@ impl DB { |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8], |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
@ -657,7 +687,7 @@ impl DB { |
|
|
|
|
value.len() as size_t, |
|
|
|
|
err_ptr); |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -667,7 +697,7 @@ impl DB { |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8], |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
@ -680,7 +710,7 @@ impl DB { |
|
|
|
|
value.len() as size_t, |
|
|
|
|
err_ptr); |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -688,7 +718,7 @@ impl DB { |
|
|
|
|
fn delete_opt(&self, |
|
|
|
|
key: &[u8], |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
@ -698,7 +728,7 @@ impl DB { |
|
|
|
|
key.len() as size_t, |
|
|
|
|
err_ptr); |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -707,7 +737,7 @@ impl DB { |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
writeopts: &WriteOptions) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
let mut err: *const i8 = 0 as *const i8; |
|
|
|
|
let err_ptr: *mut *const i8 = &mut err; |
|
|
|
@ -718,7 +748,7 @@ impl DB { |
|
|
|
|
key.len() as size_t, |
|
|
|
|
err_ptr); |
|
|
|
|
if !err.is_null() { |
|
|
|
|
return Err(error_message(err)); |
|
|
|
|
return Err(Error::new(error_message(err))); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
@ -726,7 +756,7 @@ impl DB { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Writable for DB { |
|
|
|
|
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String> { |
|
|
|
|
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { |
|
|
|
|
self.put_opt(key, value, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -734,11 +764,11 @@ impl Writable for DB { |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8]) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
self.put_cf_opt(cf, key, value, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String> { |
|
|
|
|
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { |
|
|
|
|
self.merge_opt(key, value, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -746,15 +776,15 @@ impl Writable for DB { |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8]) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
self.merge_cf_opt(cf, key, value, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn delete(&self, key: &[u8]) -> Result<(), String> { |
|
|
|
|
fn delete(&self, key: &[u8]) -> Result<(), Error> { |
|
|
|
|
self.delete_opt(key, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String> { |
|
|
|
|
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), Error> { |
|
|
|
|
self.delete_cf_opt(cf, key, &WriteOptions::default()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -786,7 +816,7 @@ impl Drop for DB { |
|
|
|
|
|
|
|
|
|
impl Writable for WriteBatch { |
|
|
|
|
/// Insert a value into the database under the given key
|
|
|
|
|
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String> { |
|
|
|
|
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
rocksdb_ffi::rocksdb_writebatch_put(self.inner, |
|
|
|
|
key.as_ptr(), |
|
|
|
@ -801,7 +831,7 @@ impl Writable for WriteBatch { |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8]) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
rocksdb_ffi::rocksdb_writebatch_put_cf(self.inner, |
|
|
|
|
cf, |
|
|
|
@ -813,7 +843,7 @@ impl Writable for WriteBatch { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String> { |
|
|
|
|
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
rocksdb_ffi::rocksdb_writebatch_merge(self.inner, |
|
|
|
|
key.as_ptr(), |
|
|
|
@ -828,7 +858,7 @@ impl Writable for WriteBatch { |
|
|
|
|
cf: DBCFHandle, |
|
|
|
|
key: &[u8], |
|
|
|
|
value: &[u8]) |
|
|
|
|
-> Result<(), String> { |
|
|
|
|
-> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
rocksdb_ffi::rocksdb_writebatch_merge_cf(self.inner, |
|
|
|
|
cf, |
|
|
|
@ -843,7 +873,7 @@ impl Writable for WriteBatch { |
|
|
|
|
/// Remove the database entry for key
|
|
|
|
|
///
|
|
|
|
|
/// Returns Err if the key was not found
|
|
|
|
|
fn delete(&self, key: &[u8]) -> Result<(), String> { |
|
|
|
|
fn delete(&self, key: &[u8]) -> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
rocksdb_ffi::rocksdb_writebatch_delete(self.inner, |
|
|
|
|
key.as_ptr(), |
|
|
|
@ -852,7 +882,7 @@ impl Writable for WriteBatch { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String> { |
|
|
|
|
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), Error> { |
|
|
|
|
unsafe { |
|
|
|
|
rocksdb_ffi::rocksdb_writebatch_delete_cf(self.inner, |
|
|
|
|
cf, |
|
|
|
@ -937,7 +967,7 @@ fn external() { |
|
|
|
|
let db = DB::open_default(path).unwrap(); |
|
|
|
|
let p = db.put(b"k1", b"v1111"); |
|
|
|
|
assert!(p.is_ok()); |
|
|
|
|
let r: Result<Option<DBVector>, String> = db.get(b"k1"); |
|
|
|
|
let r: Result<Option<DBVector>, Error> = db.get(b"k1"); |
|
|
|
|
assert!(r.unwrap().unwrap().to_utf8().unwrap() == "v1111"); |
|
|
|
|
assert!(db.delete(b"k1").is_ok()); |
|
|
|
|
assert!(db.get(b"k1").unwrap().is_none()); |
|
|
|
@ -954,10 +984,10 @@ fn errors_do_stuff() { |
|
|
|
|
let opts = Options::default(); |
|
|
|
|
// The DB will still be open when we try to destroy and the lock should fail
|
|
|
|
|
match DB::destroy(&opts, path) { |
|
|
|
|
Err(ref s) => { |
|
|
|
|
Err(s) => { |
|
|
|
|
assert!(s == |
|
|
|
|
"IO error: lock _rust_rocksdb_error/LOCK: No locks \ |
|
|
|
|
available") |
|
|
|
|
Error::new("IO error: lock _rust_rocksdb_error/LOCK: No locks \ |
|
|
|
|
available".to_string())) |
|
|
|
|
} |
|
|
|
|
Ok(_) => panic!("should fail"), |
|
|
|
|
} |
|
|
|
@ -976,7 +1006,7 @@ fn writebatch_works() { |
|
|
|
|
assert!(db.get(b"k1").unwrap().is_none()); |
|
|
|
|
let p = db.write(batch); |
|
|
|
|
assert!(p.is_ok()); |
|
|
|
|
let r: Result<Option<DBVector>, String> = db.get(b"k1"); |
|
|
|
|
let r: Result<Option<DBVector>, Error> = db.get(b"k1"); |
|
|
|
|
assert!(r.unwrap().unwrap().to_utf8().unwrap() == "v1111"); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
@ -1023,7 +1053,7 @@ fn snapshot_test() { |
|
|
|
|
assert!(p.is_ok()); |
|
|
|
|
|
|
|
|
|
let snap = db.snapshot(); |
|
|
|
|
let r: Result<Option<DBVector>, String> = snap.get(b"k1"); |
|
|
|
|
let r: Result<Option<DBVector>, Error> = snap.get(b"k1"); |
|
|
|
|
assert!(r.unwrap().unwrap().to_utf8().unwrap() == "v1111"); |
|
|
|
|
|
|
|
|
|
let p = db.put(b"k2", b"v2222"); |
|
|
|
|