Added a helper function `get_cf_names` and doc-tests refactoring

master
Oleksandr Anyshchenko 6 years ago
parent c77e301d22
commit fe26e038ab
  1. 2
      src/compaction_filter.rs
  2. 140
      src/db.rs
  3. 27
      src/lib.rs
  4. 5
      src/merge_operator.rs

@ -131,4 +131,6 @@ fn compaction_filter_test() {
assert!(db.get(b"_k").unwrap().is_none());
assert_eq!(&*db.get(b"%k").unwrap().unwrap(), b"secret");
}
let result = DB::destroy(&opts, path);
assert!(result.is_ok());
}

@ -67,16 +67,18 @@ pub enum DBRecoveryMode {
/// Making an atomic commit of several writes:
///
/// ```
/// use rocksdb::{DB, WriteBatch};
/// use rocksdb::{DB, Options, WriteBatch};
///
/// let db = DB::open_default("path/for/rocksdb/storage1").unwrap();
/// let path = "_path_for_rocksdb_storage1";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut batch = WriteBatch::default();
/// batch.put(b"my key", b"my value");
/// batch.put(b"key2", b"value2");
/// batch.put(b"key3", b"value3");
/// db.write(batch); // Atomically commits the batch
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub struct WriteBatch {
inner: *mut ffi::rocksdb_writebatch_t,
@ -89,11 +91,15 @@ pub struct ReadOptions {
/// A consistent view of the database at the point of creation.
///
/// ```
/// use rocksdb::{DB, IteratorMode};
/// use rocksdb::{DB, IteratorMode, Options};
///
/// let db = DB::open_default("path/for/rocksdb/storage3").unwrap();
/// let path = "_path_for_rocksdb_storage3";
/// {
/// let db = DB::open_default(path).unwrap();
/// let snapshot = db.snapshot(); // Creates a longer-term snapshot of the DB, but closed when goes out of scope
/// let mut iter = snapshot.iterator(IteratorMode::Start); // Make as many iterators as you'd like from one snapshot
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
///
pub struct Snapshot<'a> {
@ -110,9 +116,11 @@ pub struct Snapshot<'a> {
/// widely recognised Rust idioms.
///
/// ```
/// use rocksdb::DB;
/// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage4").unwrap();
/// let path = "_path_for_rocksdb_storage4";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
///
/// // Forwards iteration
@ -144,6 +152,8 @@ pub struct Snapshot<'a> {
/// println!("Saw {:?} {:?}", iter.key(), iter.value());
/// iter.prev();
/// }
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub struct DBRawIterator {
inner: *mut ffi::rocksdb_iterator_t,
@ -153,9 +163,11 @@ pub struct DBRawIterator {
/// ranges and direction.
///
/// ```
/// use rocksdb::{DB, Direction, IteratorMode};
/// use rocksdb::{DB, Direction, IteratorMode, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage2").unwrap();
/// let path = "_path_for_rocksdb_storage2";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.iterator(IteratorMode::Start); // Always iterates forward
/// for (key, value) in iter {
/// println!("Saw {:?} {:?}", key, value);
@ -175,6 +187,8 @@ pub struct DBRawIterator {
/// for (key, value) in iter {
/// println!("Saw {:?} {:?}", key, value);
/// }
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub struct DBIterator {
raw: DBRawIterator,
@ -228,23 +242,22 @@ impl DBRawIterator {
/// # Examples
///
/// ```rust
/// use rocksdb::DB;
/// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage5").unwrap();
/// let path = "_path_for_rocksdb_storage5";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
///
/// // Iterate all keys from the start in lexicographic order
///
/// iter.seek_to_first();
///
/// while iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value());
///
/// iter.next();
/// }
///
/// // Read just the first key
///
/// iter.seek_to_first();
///
/// if iter.valid() {
@ -252,6 +265,8 @@ impl DBRawIterator {
/// } else {
/// // There are no keys in the database
/// }
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub fn seek_to_first(&mut self) {
unsafe {
@ -264,23 +279,22 @@ impl DBRawIterator {
/// # Examples
///
/// ```rust
/// use rocksdb::DB;
/// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage6").unwrap();
/// let path = "_path_for_rocksdb_storage6";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
///
/// // Iterate all keys from the end in reverse lexicographic order
///
/// iter.seek_to_last();
///
/// while iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value());
///
/// iter.prev();
/// }
///
/// // Read just the last key
///
/// iter.seek_to_last();
///
/// if iter.valid() {
@ -288,6 +302,8 @@ impl DBRawIterator {
/// } else {
/// // There are no keys in the database
/// }
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub fn seek_to_last(&mut self) {
unsafe {
@ -303,13 +319,14 @@ impl DBRawIterator {
/// # Examples
///
/// ```rust
/// use rocksdb::DB;
/// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage7").unwrap();
/// let path = "_path_for_rocksdb_storage7";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
///
/// // Read the first key that starts with 'a'
///
/// iter.seek(b"a");
///
/// if iter.valid() {
@ -317,6 +334,8 @@ impl DBRawIterator {
/// } else {
/// // There are no keys in the database
/// }
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub fn seek(&mut self, key: &[u8]) {
unsafe {
@ -337,13 +356,14 @@ impl DBRawIterator {
/// # Examples
///
/// ```rust
/// use rocksdb::DB;
/// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage8").unwrap();
/// let path = "_path_for_rocksdb_storage8";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
///
/// // Read the last key that starts with 'a'
///
/// iter.seek_for_prev(b"b");
///
/// if iter.valid() {
@ -351,6 +371,9 @@ impl DBRawIterator {
/// } else {
/// // There are no keys in the database
/// }
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub fn seek_for_prev(&mut self, key: &[u8]) {
unsafe {
ffi::rocksdb_iter_seek_for_prev(
@ -640,9 +663,7 @@ impl DB {
if let Err(e) = fs::create_dir_all(&path) {
return Err(Error::new(format!(
"Failed to create RocksDB\
directory: `{:?}`.",
e
"Failed to create RocksDB directory: `{:?}`.", e
)));
}
@ -1395,6 +1416,39 @@ impl DBVector {
}
}
/// Retrieves a list of column families names from a given path.
pub fn get_cf_names<P: AsRef<Path>>(path: P) -> Result<Vec<String>, Error> {
let opts = Options::default();
let cpath = to_cpath(path)?;
let result: Vec<String>;
unsafe {
let mut cflen: size_t = 0;
let column_fams_raw = ffi_try!(ffi::rocksdb_list_column_families(
opts.inner,
cpath.as_ptr() as *const _,
&mut cflen,
));
let column_fams = slice::from_raw_parts(column_fams_raw, cflen as usize);
result = column_fams
.iter()
.map(|cf| CStr::from_ptr(*cf).to_string_lossy().into_owned())
.collect();
ffi::rocksdb_list_column_families_destroy(column_fams_raw, cflen);
}
Ok(result)
}
fn to_cpath<P: AsRef<Path>>(path: P) -> Result<CString, Error> {
match CString::new(path.as_ref().to_string_lossy().as_bytes()) {
Ok(c) => Ok(c),
Err(_) => Err(Error::new(
"Failed to convert path to CString when opening DB.".to_owned(),
)),
}
}
#[test]
fn test_db_vector() {
use std::mem;
@ -1425,6 +1479,7 @@ fn external() {
#[test]
fn errors_do_stuff() {
let path = "_rust_rocksdb_error";
{
let _db = DB::open_default(path).unwrap();
let opts = Options::default();
// The DB will still be open when we try to destroy it and the lock should fail.
@ -1436,6 +1491,10 @@ fn errors_do_stuff() {
}
Ok(_) => panic!("should fail"),
}
}
let opts = Options::default();
let result = DB::destroy(&opts, path);
assert!(result.is_ok());
}
#[test]
@ -1562,4 +1621,31 @@ fn set_option_test() {
];
db.set_options(&multiple_options).unwrap();
}
assert!(DB::destroy(&Options::default(), path).is_ok());
}
#[test]
fn get_cf_names_test() {
let path = "_rust_rocksdb_get_cf_names";
let opts = Options::default();
{
let db = DB::open_default(path).unwrap();
let cf_one = db.create_cf("one", &opts).unwrap();
let result = db.put_cf(cf_one, b"1", b"1");
assert!(result.is_ok());
let cf_two = db.create_cf("two", &opts).unwrap();
let result = db.put_cf(cf_two, b"2", b"2");
assert!(result.is_ok());
}
{
let cf_names = get_cf_names(path).unwrap();
let cfs = cf_names.iter().map(String::as_str).collect::<Vec<_>>();
assert_eq!(cfs, vec!["default", "one", "two"]);
let db = DB::open_cf(&opts, path, cfs.as_slice()).unwrap();
let cf_one = db.cf_handle("one").unwrap();
assert_eq!(db.get_cf(cf_one, b"1").unwrap().unwrap().as_ref(), b"1");
let cf_two = db.cf_handle("two").unwrap();
assert_eq!(db.get_cf(cf_two, b"2").unwrap().unwrap().as_ref(), b"2");
}
assert!(DB::destroy(&opts, path).is_ok());
}

@ -18,9 +18,11 @@
//! # Examples
//!
//! ```
//! use rocksdb::DB;
//! use rocksdb::{DB, Options};
//! // NB: db is automatically closed at end of lifetime
//! let db = DB::open_default("path/for/rocksdb/storage").unwrap();
//! let path = "_path_for_rocksdb_storage";
//! {
//! let db = DB::open_default(path).unwrap();
//! db.put(b"my key", b"my value");
//! match db.get(b"my key") {
//! Ok(Some(value)) => println!("retrieved value {}", value.to_utf8().unwrap()),
@ -28,12 +30,16 @@
//! Err(e) => println!("operational problem encountered: {}", e),
//! }
//! db.delete(b"my key").unwrap();
//! }
//! let _ = DB::destroy(&Options::default(), path);
//! ```
//!
//! Opening a database and a single column family with custom options:
//!
//! ```
//! use rocksdb::{DB, ColumnFamilyDescriptor, Options};
//!
//! let path = "_path_for_rocksdb_storage_with_cfs";
//! let mut cf_opts = Options::default();
//! cf_opts.set_max_write_buffer_number(16);
//! let cf = ColumnFamilyDescriptor::new("cf1", cf_opts);
@ -41,8 +47,10 @@
//! let mut db_opts = Options::default();
//! db_opts.create_missing_column_families(true);
//! db_opts.create_if_missing(true);
//!
//! let db = DB::open_cf_descriptors(&db_opts, "path/for/rocksdb/storage_with_cfs", vec![cf]).unwrap();
//! {
//! let db = DB::open_cf_descriptors(&db_opts, path, vec![cf]).unwrap();
//! }
//! let _ = DB::destroy(&db_opts, path);
//! ```
//!
@ -63,7 +71,7 @@ mod slice_transform;
pub use compaction_filter::Decision as CompactionDecision;
pub use db::{
new_bloom_filter, DBCompactionStyle, DBCompressionType, DBIterator, DBRawIterator,
get_cf_names, new_bloom_filter, DBCompactionStyle, DBCompressionType, DBIterator, DBRawIterator,
DBRecoveryMode, DBVector, Direction, IteratorMode, ReadOptions, Snapshot, WriteBatch,
};
@ -211,10 +219,11 @@ pub struct Options {
/// Making an unsafe write of a batch:
///
/// ```
/// use rocksdb::{DB, WriteBatch, WriteOptions};
///
/// let db = DB::open_default("path/for/rocksdb/storageY").unwrap();
/// use rocksdb::{DB, Options, WriteBatch, WriteOptions};
///
/// let path = "_path_for_rocksdb_storageY";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut batch = WriteBatch::default();
/// batch.put(b"my key", b"my value");
/// batch.put(b"key2", b"value2");
@ -225,6 +234,8 @@ pub struct Options {
/// write_options.disable_wal(true);
///
/// db.write_opt(batch, &write_options);
/// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub struct WriteOptions {
inner: *mut ffi::rocksdb_writeoptions_t,

@ -38,10 +38,11 @@
//! }
//!
//! fn main() {
//! let path = "path/to/rocksdb";
//! let path = "_rust_path_to_rocksdb";
//! let mut opts = Options::default();
//! opts.create_if_missing(true);
//! opts.set_merge_operator("test operator", concat_merge, None);
//! {
//! let db = DB::open(&opts, path).unwrap();
//! let p = db.put(b"k1", b"a");
//! db.merge(b"k1", b"b");
@ -51,6 +52,8 @@
//! let r = db.get(b"k1");
//! assert!(r.unwrap().unwrap().to_utf8().unwrap() == "abcdefg");
//! }
//! let _ = DB::destroy(&opts, path);
//! }
//! ```
use libc::{self, c_char, c_int, c_void, size_t};

Loading…
Cancel
Save