|
|
@ -118,7 +118,11 @@ pub trait Cursor<'txn> { |
|
|
|
K: AsRef<[u8]>, |
|
|
|
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) => { |
|
|
|
|
|
|
|
self.get(None, None, ffi::MDB_LAST).ok(); |
|
|
|
|
|
|
|
return Iter::new(self.cursor(), ffi::MDB_NEXT, ffi::MDB_NEXT); |
|
|
|
|
|
|
|
}, |
|
|
|
Err(error) => return Iter::Err(error), |
|
|
|
Err(error) => return Iter::Err(error), |
|
|
|
}; |
|
|
|
}; |
|
|
|
Iter::new(self.cursor(), ffi::MDB_GET_CURRENT, ffi::MDB_NEXT_DUP) |
|
|
|
Iter::new(self.cursor(), ffi::MDB_GET_CURRENT, ffi::MDB_NEXT_DUP) |
|
|
@ -652,6 +656,44 @@ mod test { |
|
|
|
assert_eq!(0, cursor.iter_dup_of(b"foo").count()); |
|
|
|
assert_eq!(0, cursor.iter_dup_of(b"foo").count()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
|
|
|
fn test_iter_del_get() { |
|
|
|
|
|
|
|
let dir = TempDir::new("test").unwrap(); |
|
|
|
|
|
|
|
let env = Environment::new().open(dir.path()).unwrap(); |
|
|
|
|
|
|
|
let db = env.create_db(None, DatabaseFlags::DUP_SORT).unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let items: Vec<(&[u8], &[u8])> = vec![(b"a", b"1"), (b"b", b"2")]; |
|
|
|
|
|
|
|
let r: Vec<(&[u8], &[u8])> = Vec::new(); |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
let txn = env.begin_ro_txn().unwrap(); |
|
|
|
|
|
|
|
let mut cursor = txn.open_ro_cursor(db).unwrap(); |
|
|
|
|
|
|
|
assert_eq!(r, cursor.iter_dup_of(b"a").collect::<Result<Vec<_>>>().unwrap()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
let mut txn = env.begin_rw_txn().unwrap(); |
|
|
|
|
|
|
|
for &(ref key, ref data) in &items { |
|
|
|
|
|
|
|
txn.put(db, key, data, WriteFlags::empty()).unwrap(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
txn.commit().unwrap(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut txn = env.begin_rw_txn().unwrap(); |
|
|
|
|
|
|
|
let mut cursor = txn.open_rw_cursor(db).unwrap(); |
|
|
|
|
|
|
|
assert_eq!(items, cursor.iter_dup().flat_map(|x| x).collect::<Result<Vec<_>>>().unwrap()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!( |
|
|
|
|
|
|
|
items.clone().into_iter().take(1).collect::<Vec<(&[u8], &[u8])>>(), |
|
|
|
|
|
|
|
cursor.iter_dup_of(b"a").collect::<Result<Vec<_>>>().unwrap() |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!((None, &b"1"[..]), cursor.get(Some(b"a"), Some(b"1"), MDB_SET).unwrap()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cursor.del(WriteFlags::empty()).unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(r, cursor.iter_dup_of(b"a").collect::<Result<Vec<_>>>().unwrap()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
#[test] |
|
|
|
fn test_put_del() { |
|
|
|
fn test_put_del() { |
|
|
|
let dir = TempDir::new("test").unwrap(); |
|
|
|
let dir = TempDir::new("test").unwrap(); |
|
|
|