added test for deleting values from an iter_dup db

without.crypto
Rick Richardson 6 years ago
parent f8a4dbf3f0
commit 8599e4051e
  1. 4
      src/cursor.rs
  2. 56
      src/transaction.rs

@ -80,7 +80,7 @@ pub trait Cursor<'txn> {
/// Iterate over duplicate items in the database starting from the given /// Iterate over duplicate items in the database starting from the given
/// key. Each item will be returned as an iterator of its duplicates. /// key. Each item will be returned as an iterator of its duplicates.
fn iter_dup_from<K>(&mut self, key: &K) -> IterDup<'txn> where K: AsRef<[u8]> { fn iter_dup_from<K>(&mut self, key: K) -> IterDup<'txn> where K: AsRef<[u8]> {
match self.get(Some(key.as_ref()), None, ffi::MDB_SET_RANGE) { match self.get(Some(key.as_ref()), None, ffi::MDB_SET_RANGE) {
Ok(_) | Err(Error::NotFound) => (), Ok(_) | Err(Error::NotFound) => (),
Err(error) => panic!("mdb_cursor_get returned an unexpected error: {}", error), Err(error) => panic!("mdb_cursor_get returned an unexpected error: {}", error),
@ -89,7 +89,7 @@ pub trait Cursor<'txn> {
} }
/// Iterate over the duplicates of the item in the database with the given key. /// Iterate over the duplicates of the item in the database with the given key.
fn iter_dup_of<K>(&mut self, key: &K) -> Iter<'txn> where K: AsRef<[u8]> { fn iter_dup_of<K>(&mut self, key: K) -> Iter<'txn> where K: AsRef<[u8]> {
match self.get(Some(key.as_ref()), None, ffi::MDB_SET) { match self.get(Some(key.as_ref()), None, ffi::MDB_SET) {
Ok(_) | Err(Error::NotFound) => (), Ok(_) | Err(Error::NotFound) => (),
Err(error) => panic!("mdb_cursor_get returned an unexpected error: {}", error), Err(error) => panic!("mdb_cursor_get returned an unexpected error: {}", error),

@ -275,6 +275,11 @@ impl <'env> RwTransaction<'env> {
mv_data: key.as_ptr() as *mut c_void }; mv_data: key.as_ptr() as *mut c_void };
let mut data_val: ffi::MDB_val = ffi::MDB_val { mv_size: data.len() as size_t, let mut data_val: ffi::MDB_val = ffi::MDB_val { mv_size: data.len() as size_t,
mv_data: data.as_ptr() as *mut c_void }; mv_data: data.as_ptr() as *mut c_void };
/*
unsafe { println!("put {:?} {:?}",
std::slice::from_raw_parts(key_val.mv_data as *const u8, key_val.mv_size),
std::slice::from_raw_parts(data_val.mv_data as *const u8, data_val.mv_size)) };
*/
unsafe { unsafe {
lmdb_result(ffi::mdb_put(self.txn(), lmdb_result(ffi::mdb_put(self.txn(),
database.dbi(), database.dbi(),
@ -332,6 +337,13 @@ impl <'env> RwTransaction<'env> {
let data_val: Option<ffi::MDB_val> = let data_val: Option<ffi::MDB_val> =
data.map(|data| ffi::MDB_val { mv_size: data.len() as size_t, data.map(|data| ffi::MDB_val { mv_size: data.len() as size_t,
mv_data: data.as_ptr() as *mut c_void }); mv_data: data.as_ptr() as *mut c_void });
/*
data_val.as_ref().map(|v| unsafe {
println!("del {:?} {:?}",
std::slice::from_raw_parts(key_val.mv_data as *const u8, key_val.mv_size),
std::slice::from_raw_parts(v.mv_data as *const u8, v.mv_size)) });
*/
unsafe { unsafe {
lmdb_result(ffi::mdb_del(self.txn(), lmdb_result(ffi::mdb_del(self.txn(),
database.dbi(), database.dbi(),
@ -392,6 +404,7 @@ mod test {
use flags::*; use flags::*;
use super::*; use super::*;
use test_utils::*; use test_utils::*;
use cursor::Cursor;
#[test] #[test]
fn test_put_get_del() { fn test_put_get_del() {
@ -414,6 +427,49 @@ mod test {
txn.del(db, b"key1", None).unwrap(); txn.del(db, b"key1", None).unwrap();
assert_eq!(txn.get(db, b"key1"), Err(Error::NotFound)); assert_eq!(txn.get(db, b"key1"), Err(Error::NotFound));
} }
#[test]
fn test_put_get_del_multi() {
let dir = TempDir::new("test").unwrap();
let env = Environment::new().open(dir.path()).unwrap();
let db = env.create_db(Some("putgetdel"), DatabaseFlags::DUP_SORT).unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key1", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key1", b"val3", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val3", WriteFlags::empty()).unwrap();
txn.put(db, b"key3", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key3", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key3", b"val3", WriteFlags::empty()).unwrap();
txn.commit().unwrap();
let txn = env.begin_rw_txn().unwrap();
{
let mut cur = txn.open_ro_cursor(db).unwrap();
let iter = cur.iter_dup_of(b"key1");
let vals = iter.map(|(_,x)| x).collect::<Vec<_>>();
assert_eq!(vals, vec![b"val1", b"val2", b"val3"]);
}
txn.commit().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.del(db, b"key1", Some(b"val2")).unwrap();
txn.commit().unwrap();
let txn = env.begin_rw_txn().unwrap();
{
let mut cur = txn.open_ro_cursor(db).unwrap();
let iter = cur.iter_dup_of(b"key1");
let vals = iter.map(|(_,x)| x).collect::<Vec<_>>();
assert_eq!(vals, vec![b"val1", b"val3"]);
}
txn.commit().unwrap();
}
#[test] #[test]
fn test_reserve() { fn test_reserve() {

Loading…
Cancel
Save