From 3a069ff4dc5ded1c96d724c71ea75cbf9cdc6322 Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 10 Feb 2019 17:29:41 +0000 Subject: [PATCH] Return a Result from property getters --- src/db.rs | 80 +++++++++++++++++++++++++++++++++--------- tests/test_property.rs | 6 ++-- 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/db.rs b/src/db.rs index b2a5912..09edb42 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1153,45 +1153,93 @@ impl DB { }) } - pub fn property_value(&self, name: &str) -> Option { - let prop_name = CString::new(name).unwrap(); + /// Retrieves a RocksDB property by name. + /// + /// For a full list of properties, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L428-L634 + pub fn property_value(&self, name: &str) -> Result, Error> { + let prop_name = match CString::new(name) { + Ok(c) => c, + Err(e) => { + return Err(Error::new(format!("Failed to convert property name to CString: {}", e))) + } + }; + unsafe { let value = ffi::rocksdb_property_value(self.inner, prop_name.as_ptr()); if value.is_null() { - return None; + return Ok(None); } - let s = CStr::from_ptr(value).to_str().unwrap().to_owned(); + let str_value = match CStr::from_ptr(value).to_str() { + Ok(s) => s.to_owned(), + Err(e) => { + return Err(Error::new(format!("Failed to convert property value to string: {}", e))) + } + }; + libc::free(value as *mut c_void); - Some(s) + Ok(Some(str_value)) } } - pub fn property_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { - let prop_name = CString::new(name).unwrap(); + /// Retrieves a RocksDB property by name, for a specific column family. + /// + /// For a full list of properties, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L428-L634 + pub fn property_value_cf(&self, cf: ColumnFamily, name: &str) -> Result, Error> { + let prop_name = match CString::new(name) { + Ok(c) => c, + Err(e) => { + return Err(Error::new(format!("Failed to convert property name to CString: {}", e))) + } + }; + unsafe { let value = ffi::rocksdb_property_value_cf(self.inner, cf.inner, prop_name.as_ptr()); if value.is_null() { - return None; + return Ok(None); } - let s = CStr::from_ptr(value).to_str().unwrap().to_owned(); + let str_value = match CStr::from_ptr(value).to_str() { + Ok(s) => s.to_owned(), + Err(e) => { + return Err(Error::new(format!("Failed to convert property value to string: {}", e))) + } + }; + libc::free(value as *mut c_void); - Some(s) + Ok(Some(str_value)) } } - pub fn property_int_value(&self, name: &str) -> Option { + /// Retrieves a RocksDB property and casts it to an integer. + /// + /// For a full list of properties that return int values, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L654-L689 + pub fn property_int_value(&self, name: &str) -> Result, Error> { match self.property_value(name) { - Some(value) => value.parse::().ok(), - None => None, + Ok(Some(value)) => match value.parse::() { + Ok(int_value) => Ok(Some(int_value)), + Err(e) => Err(Error::new(format!("Failed to convert property value to int: {}", e))), + } + Ok(None) => Ok(None), + Err(e) => Err(e), } } - pub fn property_int_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { + /// Retrieves a RocksDB property for a specific column family and casts it to an integer. + /// + /// For a full list of properties that return int values, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L654-L689 + pub fn property_int_value_cf(&self, cf: ColumnFamily, name: &str) -> Result, Error> { match self.property_value_cf(cf, name) { - Some(value) => value.parse::().ok(), - None => None, + Ok(Some(value)) => match value.parse::() { + Ok(int_value) => Ok(Some(int_value)), + Err(e) => Err(Error::new(format!("Failed to convert property value to int: {}", e))), + } + Ok(None) => Ok(None), + Err(e) => Err(e), } } } diff --git a/tests/test_property.rs b/tests/test_property.rs index 222755b..c2be439 100644 --- a/tests/test_property.rs +++ b/tests/test_property.rs @@ -27,7 +27,7 @@ fn property_test() { .property_int_value("rocksdb.estimate-live-data-size") .unwrap(); - assert!(value == 0); + assert!(value == Some(0)); } } @@ -40,8 +40,8 @@ fn property_cf_test() { let cf = db.create_cf("cf1", &opts).unwrap(); let total_keys = db .property_int_value_cf(cf, "rocksdb.estimate-num-keys") - .unwrap() as usize; + .unwrap(); - assert!(total_keys == 0); + assert!(total_keys == Some(0)); } }