Merge pull request #241 from aleksuss/get-cf-names

Some doc-tests refactoring
master
Jordan Terrell 6 years ago committed by GitHub
commit f4bd7c39f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/compaction_filter.rs
  2. 294
      src/db.rs
  3. 57
      src/lib.rs
  4. 21
      src/merge_operator.rs

@ -131,4 +131,6 @@ fn compaction_filter_test() {
assert!(db.get(b"_k").unwrap().is_none()); assert!(db.get(b"_k").unwrap().is_none());
assert_eq!(&*db.get(b"%k").unwrap().unwrap(), b"secret"); 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: /// 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(); /// let mut batch = WriteBatch::default();
/// batch.put(b"my key", b"my value"); /// batch.put(b"my key", b"my value");
/// batch.put(b"key2", b"value2"); /// batch.put(b"key2", b"value2");
/// batch.put(b"key3", b"value3"); /// batch.put(b"key3", b"value3");
/// db.write(batch); // Atomically commits the batch /// db.write(batch); // Atomically commits the batch
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ``` /// ```
pub struct WriteBatch { pub struct WriteBatch {
inner: *mut ffi::rocksdb_writebatch_t, inner: *mut ffi::rocksdb_writebatch_t,
@ -89,11 +91,15 @@ pub struct ReadOptions {
/// A consistent view of the database at the point of creation. /// 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 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 = 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> { pub struct Snapshot<'a> {
@ -110,40 +116,44 @@ pub struct Snapshot<'a> {
/// widely recognised Rust idioms. /// 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 mut iter = db.raw_iterator(); /// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// // Forwards iteration /// // Forwards iteration
/// iter.seek_to_first(); /// iter.seek_to_first();
/// while iter.valid() { /// while iter.valid() {
/// println!("Saw {:?} {:?}", iter.key(), iter.value()); /// println!("Saw {:?} {:?}", iter.key(), iter.value());
/// iter.next(); /// iter.next();
/// } /// }
/// ///
/// // Reverse iteration /// // Reverse iteration
/// iter.seek_to_last(); /// iter.seek_to_last();
/// while iter.valid() { /// while iter.valid() {
/// println!("Saw {:?} {:?}", iter.key(), iter.value()); /// println!("Saw {:?} {:?}", iter.key(), iter.value());
/// iter.prev(); /// iter.prev();
/// } /// }
/// ///
/// // Seeking /// // Seeking
/// iter.seek(b"my key"); /// iter.seek(b"my key");
/// while iter.valid() { /// while iter.valid() {
/// println!("Saw {:?} {:?}", iter.key(), iter.value()); /// println!("Saw {:?} {:?}", iter.key(), iter.value());
/// iter.next(); /// iter.next();
/// } /// }
/// ///
/// // Reverse iteration from key /// // Reverse iteration from key
/// // Note, use seek_for_prev when reversing because if this key doesn't exist, /// // Note, use seek_for_prev when reversing because if this key doesn't exist,
/// // this will make the iterator start from the previous key rather than the next. /// // this will make the iterator start from the previous key rather than the next.
/// iter.seek_for_prev(b"my key"); /// iter.seek_for_prev(b"my key");
/// while iter.valid() { /// while iter.valid() {
/// println!("Saw {:?} {:?}", iter.key(), iter.value()); /// println!("Saw {:?} {:?}", iter.key(), iter.value());
/// iter.prev(); /// iter.prev();
/// }
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ``` /// ```
pub struct DBRawIterator { pub struct DBRawIterator {
inner: *mut ffi::rocksdb_iterator_t, inner: *mut ffi::rocksdb_iterator_t,
@ -153,28 +163,32 @@ pub struct DBRawIterator {
/// ranges and direction. /// 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 mut iter = db.iterator(IteratorMode::Start); // Always iterates forward /// {
/// for (key, value) in iter { /// let db = DB::open_default(path).unwrap();
/// println!("Saw {:?} {:?}", key, value); /// let mut iter = db.iterator(IteratorMode::Start); // Always iterates forward
/// } /// for (key, value) in iter {
/// iter = db.iterator(IteratorMode::End); // Always iterates backward /// println!("Saw {:?} {:?}", key, value);
/// for (key, value) in iter { /// }
/// println!("Saw {:?} {:?}", key, value); /// iter = db.iterator(IteratorMode::End); // Always iterates backward
/// } /// for (key, value) in iter {
/// iter = db.iterator(IteratorMode::From(b"my key", Direction::Forward)); // From a key in Direction::{forward,reverse} /// println!("Saw {:?} {:?}", key, value);
/// for (key, value) in iter { /// }
/// println!("Saw {:?} {:?}", key, value); /// iter = db.iterator(IteratorMode::From(b"my key", Direction::Forward)); // From a key in Direction::{forward,reverse}
/// } /// for (key, value) in iter {
/// println!("Saw {:?} {:?}", key, value);
/// }
/// ///
/// // You can seek with an existing Iterator instance, too /// // You can seek with an existing Iterator instance, too
/// iter = db.iterator(IteratorMode::Start); /// iter = db.iterator(IteratorMode::Start);
/// iter.set_mode(IteratorMode::From(b"another key", Direction::Reverse)); /// iter.set_mode(IteratorMode::From(b"another key", Direction::Reverse));
/// for (key, value) in iter { /// for (key, value) in iter {
/// println!("Saw {:?} {:?}", key, value); /// println!("Saw {:?} {:?}", key, value);
/// }
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ``` /// ```
pub struct DBIterator { pub struct DBIterator {
raw: DBRawIterator, raw: DBRawIterator,
@ -228,30 +242,31 @@ impl DBRawIterator {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```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 mut iter = db.raw_iterator(); /// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// // Iterate all keys from the start in lexicographic order /// // Iterate all keys from the start in lexicographic order
/// iter.seek_to_first();
/// ///
/// iter.seek_to_first(); /// while iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value());
/// iter.next();
/// }
/// ///
/// while iter.valid() { /// // Read just the first key
/// println!("{:?} {:?}", iter.key(), iter.value()); /// iter.seek_to_first();
/// ///
/// iter.next(); /// if iter.valid() {
/// } /// println!("{:?} {:?}", iter.key(), iter.value());
/// /// } else {
/// // Read just the first key /// // There are no keys in the database
/// /// }
/// iter.seek_to_first();
///
/// if iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value());
/// } else {
/// // There are no keys in the database
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ``` /// ```
pub fn seek_to_first(&mut self) { pub fn seek_to_first(&mut self) {
unsafe { unsafe {
@ -264,30 +279,31 @@ impl DBRawIterator {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use rocksdb::DB; /// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage6").unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// // Iterate all keys from the end in reverse lexicographic order /// let path = "_path_for_rocksdb_storage6";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// iter.seek_to_last(); /// // Iterate all keys from the end in reverse lexicographic order
/// iter.seek_to_last();
/// ///
/// while iter.valid() { /// while iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value()); /// println!("{:?} {:?}", iter.key(), iter.value());
/// iter.prev();
/// }
/// ///
/// iter.prev(); /// // Read just the last key
/// } /// iter.seek_to_last();
///
/// // Read just the last key
///
/// iter.seek_to_last();
/// ///
/// if iter.valid() { /// if iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value()); /// println!("{:?} {:?}", iter.key(), iter.value());
/// } else { /// } else {
/// // There are no keys in the database /// // There are no keys in the database
/// }
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ``` /// ```
pub fn seek_to_last(&mut self) { pub fn seek_to_last(&mut self) {
unsafe { unsafe {
@ -303,20 +319,23 @@ impl DBRawIterator {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```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 mut iter = db.raw_iterator(); /// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// // Read the first key that starts with 'a' /// // Read the first key that starts with 'a'
/// iter.seek(b"a");
/// ///
/// iter.seek(b"a"); /// if iter.valid() {
/// /// println!("{:?} {:?}", iter.key(), iter.value());
/// if iter.valid() { /// } else {
/// println!("{:?} {:?}", iter.key(), iter.value()); /// // There are no keys in the database
/// } else { /// }
/// // There are no keys in the database
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ``` /// ```
pub fn seek(&mut self, key: &[u8]) { pub fn seek(&mut self, key: &[u8]) {
unsafe { unsafe {
@ -337,20 +356,24 @@ impl DBRawIterator {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use rocksdb::DB; /// use rocksdb::{DB, Options};
///
/// let mut db = DB::open_default("path/for/rocksdb/storage8").unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// // Read the last key that starts with 'a' /// let path = "_path_for_rocksdb_storage8";
/// {
/// let db = DB::open_default(path).unwrap();
/// let mut iter = db.raw_iterator();
/// ///
/// iter.seek_for_prev(b"b"); /// // Read the last key that starts with 'a'
/// iter.seek_for_prev(b"b");
/// ///
/// if iter.valid() { /// if iter.valid() {
/// println!("{:?} {:?}", iter.key(), iter.value()); /// println!("{:?} {:?}", iter.key(), iter.value());
/// } else { /// } else {
/// // There are no keys in the database /// // There are no keys in the database
/// }
/// } /// }
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub fn seek_for_prev(&mut self, key: &[u8]) { pub fn seek_for_prev(&mut self, key: &[u8]) {
unsafe { unsafe {
ffi::rocksdb_iter_seek_for_prev( ffi::rocksdb_iter_seek_for_prev(
@ -640,9 +663,7 @@ impl DB {
if let Err(e) = fs::create_dir_all(&path) { if let Err(e) = fs::create_dir_all(&path) {
return Err(Error::new(format!( return Err(Error::new(format!(
"Failed to create RocksDB\ "Failed to create RocksDB directory: `{:?}`.", e
directory: `{:?}`.",
e
))); )));
} }
@ -719,17 +740,7 @@ impl DB {
} }
pub fn list_cf<P: AsRef<Path>>(opts: &Options, path: P) -> Result<Vec<String>, Error> { pub fn list_cf<P: AsRef<Path>>(opts: &Options, path: P) -> Result<Vec<String>, Error> {
let cpath = match CString::new(path.as_ref().to_string_lossy().as_bytes()) { let cpath = to_cpath(path)?;
Ok(c) => c,
Err(_) => {
return Err(Error::new(
"Failed to convert path to CString \
when opening DB."
.to_owned(),
))
}
};
let mut length = 0; let mut length = 0;
unsafe { unsafe {
@ -749,7 +760,7 @@ impl DB {
} }
pub fn destroy<P: AsRef<Path>>(opts: &Options, path: P) -> Result<(), Error> { pub fn destroy<P: AsRef<Path>>(opts: &Options, path: P) -> Result<(), Error> {
let cpath = CString::new(path.as_ref().to_string_lossy().as_bytes()).unwrap(); let cpath = to_cpath(path)?;
unsafe { unsafe {
ffi_try!(ffi::rocksdb_destroy_db(opts.inner, cpath.as_ptr(),)); ffi_try!(ffi::rocksdb_destroy_db(opts.inner, cpath.as_ptr(),));
} }
@ -757,7 +768,7 @@ impl DB {
} }
pub fn repair<P: AsRef<Path>>(opts: Options, path: P) -> Result<(), Error> { pub fn repair<P: AsRef<Path>>(opts: Options, path: P) -> Result<(), Error> {
let cpath = CString::new(path.as_ref().to_string_lossy().as_bytes()).unwrap(); let cpath = to_cpath(path)?;
unsafe { unsafe {
ffi_try!(ffi::rocksdb_repair_db(opts.inner, cpath.as_ptr(),)); ffi_try!(ffi::rocksdb_repair_db(opts.inner, cpath.as_ptr(),));
} }
@ -1403,6 +1414,15 @@ impl DBVector {
} }
} }
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] #[test]
fn test_db_vector() { fn test_db_vector() {
use std::mem; use std::mem;
@ -1433,17 +1453,22 @@ fn external() {
#[test] #[test]
fn errors_do_stuff() { fn errors_do_stuff() {
let path = "_rust_rocksdb_error"; let path = "_rust_rocksdb_error";
let _db = DB::open_default(path).unwrap(); {
let opts = Options::default(); let _db = DB::open_default(path).unwrap();
// The DB will still be open when we try to destroy it and the lock should fail. let opts = Options::default();
match DB::destroy(&opts, path) { // The DB will still be open when we try to destroy it and the lock should fail.
Err(s) => { match DB::destroy(&opts, path) {
let message = s.to_string(); Err(s) => {
assert!(message.find("IO error:").is_some()); let message = s.to_string();
assert!(message.find("_rust_rocksdb_error/LOCK:").is_some()); assert!(message.find("IO error:").is_some());
assert!(message.find("_rust_rocksdb_error/LOCK:").is_some());
}
Ok(_) => panic!("should fail"),
} }
Ok(_) => panic!("should fail"),
} }
let opts = Options::default();
let result = DB::destroy(&opts, path);
assert!(result.is_ok());
} }
#[test] #[test]
@ -1570,4 +1595,5 @@ fn set_option_test() {
]; ];
db.set_options(&multiple_options).unwrap(); db.set_options(&multiple_options).unwrap();
} }
assert!(DB::destroy(&Options::default(), path).is_ok());
} }

@ -18,22 +18,28 @@
//! # Examples //! # Examples
//! //!
//! ``` //! ```
//! use rocksdb::DB; //! use rocksdb::{DB, Options};
//! // NB: db is automatically closed at end of lifetime //! // 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";
//! db.put(b"my key", b"my value"); //! {
//! match db.get(b"my key") { //! let db = DB::open_default(path).unwrap();
//! Ok(Some(value)) => println!("retrieved value {}", value.to_utf8().unwrap()), //! db.put(b"my key", b"my value");
//! Ok(None) => println!("value not found"), //! match db.get(b"my key") {
//! Err(e) => println!("operational problem encountered: {}", e), //! Ok(Some(value)) => println!("retrieved value {}", value.to_utf8().unwrap()),
//! } //! Ok(None) => println!("value not found"),
//! db.delete(b"my key").unwrap(); //! 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: //! Opening a database and a single column family with custom options:
//! //!
//! ``` //! ```
//! use rocksdb::{DB, ColumnFamilyDescriptor, Options}; //! use rocksdb::{DB, ColumnFamilyDescriptor, Options};
//!
//! let path = "_path_for_rocksdb_storage_with_cfs";
//! let mut cf_opts = Options::default(); //! let mut cf_opts = Options::default();
//! cf_opts.set_max_write_buffer_number(16); //! cf_opts.set_max_write_buffer_number(16);
//! let cf = ColumnFamilyDescriptor::new("cf1", cf_opts); //! let cf = ColumnFamilyDescriptor::new("cf1", cf_opts);
@ -41,8 +47,10 @@
//! let mut db_opts = Options::default(); //! let mut db_opts = Options::default();
//! db_opts.create_missing_column_families(true); //! db_opts.create_missing_column_families(true);
//! db_opts.create_if_missing(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);
//! ``` //! ```
//! //!
@ -211,20 +219,23 @@ pub struct Options {
/// Making an unsafe write of a batch: /// Making an unsafe write of a batch:
/// ///
/// ``` /// ```
/// use rocksdb::{DB, WriteBatch, WriteOptions}; /// use rocksdb::{DB, Options, WriteBatch, WriteOptions};
/// ///
/// let db = DB::open_default("path/for/rocksdb/storageY").unwrap(); /// 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");
/// batch.put(b"key3", b"value3");
/// ///
/// let mut batch = WriteBatch::default(); /// let mut write_options = WriteOptions::default();
/// batch.put(b"my key", b"my value"); /// write_options.set_sync(false);
/// batch.put(b"key2", b"value2"); /// write_options.disable_wal(true);
/// batch.put(b"key3", b"value3");
/// ///
/// let mut write_options = WriteOptions::default(); /// db.write_opt(batch, &write_options);
/// write_options.set_sync(false); /// }
/// write_options.disable_wal(true); /// let _ = DB::destroy(&Options::default(), path);
///
/// db.write_opt(batch, &write_options);
/// ``` /// ```
pub struct WriteOptions { pub struct WriteOptions {
inner: *mut ffi::rocksdb_writeoptions_t, inner: *mut ffi::rocksdb_writeoptions_t,

@ -38,18 +38,21 @@
//! } //! }
//! //!
//! fn main() { //! fn main() {
//! let path = "path/to/rocksdb"; //! let path = "_rust_path_to_rocksdb";
//! let mut opts = Options::default(); //! let mut opts = Options::default();
//! opts.create_if_missing(true); //! opts.create_if_missing(true);
//! opts.set_merge_operator("test operator", concat_merge, None); //! opts.set_merge_operator("test operator", concat_merge, None);
//! let db = DB::open(&opts, path).unwrap(); //! {
//! let p = db.put(b"k1", b"a"); //! let db = DB::open(&opts, path).unwrap();
//! db.merge(b"k1", b"b"); //! let p = db.put(b"k1", b"a");
//! db.merge(b"k1", b"c"); //! db.merge(b"k1", b"b");
//! db.merge(b"k1", b"d"); //! db.merge(b"k1", b"c");
//! db.merge(b"k1", b"efg"); //! db.merge(b"k1", b"d");
//! let r = db.get(b"k1"); //! db.merge(b"k1", b"efg");
//! assert!(r.unwrap().unwrap().to_utf8().unwrap() == "abcdefg"); //! let r = db.get(b"k1");
//! assert!(r.unwrap().unwrap().to_utf8().unwrap() == "abcdefg");
//! }
//! let _ = DB::destroy(&opts, path);
//! } //! }
//! ``` //! ```

Loading…
Cancel
Save