Struct ord_lmdb_zero::Cursor
source · [−]pub struct Cursor<'txn, 'db> { /* private fields */ }
Expand description
A cursor into an LMDB database.
Depending on the context, a cursor’s lifetime may be scoped to a transaction or to the whole environment. Its lifetime is also naturally bound to the lifetime of the database it cursors into.
Creation and Ownership
Cursors are normally created by calling .cursor()
on the transaction that
is to own them. Since a Cursor
is associated with a Database
, this also
involves passing a reference or other handle to that Database
to the
call.
For the Database
, all three ownership models are permitted, though owned
likely is not useful. The transaction can be used with borrowed or shared
ownership, but note that shared ownership requires having the
CreateCursor
trait imported.
Example — Traditional “keep everything on the stack” style
This is the simplest way to use Cursor
, but not always the easiest. Most
examples in the documentation use this method. Here, the Cursor
holds
references to the transaction and the database. This makes it somewhat
inflexible; for example, you cannot make a structure which owns both the
transaction and some set of cursors.
// N.B. Unneeded type and lifetime annotations here for clarity.
fn run<'db, 'txn>(txn: &'txn lmdb::WriteTransaction,
access: &'txn mut lmdb::WriteAccessor,
db: &'db lmdb::Database) {
let mut cursor: lmdb::Cursor<'txn, 'db> = txn.cursor(db).unwrap();
// Do stuff with cursor.
}
Example — Use reference counting for more flexibility
use std::sync::Arc;
// We need to import the `CreateCursor` trait to be able to use shared
// mode cursors. `TxExt` also gets us `to_const()` used below.
use lmdb::traits::{CreateCursor, TxExt};
// This approach lets us make this `Context` struct wherein we can pass
// around everything our functions might need in one piece as well as
// having more flexible transaction lifetimes.
struct Context {
txn: Arc<lmdb::ConstTransaction<'static>>,
cursor: Arc<lmdb::Cursor<'static,'static>>,
}
// N.B. Unneeded type and lifetime annotations here for clarity.
// Everything at higher levels also needs to have `'static` lifetimes.
// Here, we just stuff everything into `Arc`s for simplicity.
let env: Arc<lmdb::Environment> = Arc::new(create_env());
let db: Arc<lmdb::Database<'static>> = Arc::new(lmdb::Database::open(
env.clone(), None, &lmdb::DatabaseOptions::defaults()).unwrap());
// Now we can make our transaction and cursor and pass them around as one.
// Note that you can also use plain `Rc` at this level, too.
let txn: Arc<lmdb::WriteTransaction<'static>> =
Arc::new(lmdb::WriteTransaction::new(env.clone()).unwrap());
let cursor: Arc<lmdb::Cursor<'static, 'static>> = Arc::new(
txn.cursor(db.clone()).unwrap());
let context = Context { txn: txn.clone().to_const(), cursor: cursor };
do_stuff(&context);
// Drop the context so we can get the `WriteTransaction` back
// and commit it.
drop(context);
let txn = Arc::try_unwrap(txn).unwrap();
txn.commit().unwrap();
#[allow(unused_vars)]
fn do_stuff(context: &Context) {
// do stuff
}
Lifetime
A cursor must be strictly outlived by both the transaction that created it and by the database into which it indexes. The two lifetimes are needed to permit a cursor to be disassociated from its transaction and rebound to a later transaction.
Cursor
is covariant on both of its lifetimes. If you have an owned
Cursor
as a structure member and don’t plan on using the dissoc_cursor
API, you can use one lifetime parameter to fill both without issue.
struct CursorOwner<'a> {
cursor: lmdb::Cursor<'a, 'a>,
}
fn covariance<'a, 'txn: 'a, 'db: 'a>(c: lmdb::Cursor<'txn,'db>)
-> CursorOwner<'a> {
let c: lmdb::Cursor<'a, 'a> = c;
CursorOwner { cursor: c }
}
Note that an &mut Cursor<'txn,'db>
is naturally invariant on both
lifetimes. This means that structures containing &mut Cursor
or functions
taking them as references should generally include both.
// Write this
fn do_stuff_with_cursor<'txn, 'db>(c: &mut lmdb::Cursor<'txn,'db>) {
// Stuff
}
// Not this
fn do_stuff_with_cursor_2<'a>(c: &mut lmdb::Cursor<'a,'a>) {
// Stuff
}
Attempting to unify the lifetimes on a &mut Cursor
will often work, but
can also cause the compiler to infer lifetimes in unfavourable ways.
Implementations
sourceimpl<'txn, 'db> Cursor<'txn, 'db>
impl<'txn, 'db> Cursor<'txn, 'db>
sourcepub fn construct(
txn: NonSyncSupercow<'txn, ConstTransaction<'txn>>,
db: Supercow<'db, Database<'db>>
) -> Result<Self>
pub fn construct(
txn: NonSyncSupercow<'txn, ConstTransaction<'txn>>,
db: Supercow<'db, Database<'db>>
) -> Result<Self>
Directly construct a cursor with the given transaction and database handles.
This is a low-level function intended only for use by implementations
of the CreateCursor
trait. (There is nothing less safe about it being
low-level; it’s simply inconvenient.)
sourcepub fn from_stale(
stale: StaleCursor<'db>,
txn: NonSyncSupercow<'txn, ConstTransaction<'txn>>
) -> Result<Self>
pub fn from_stale(
stale: StaleCursor<'db>,
txn: NonSyncSupercow<'txn, ConstTransaction<'txn>>
) -> Result<Self>
Directly renew a StaleCursor
into a functional Cursor
using the
given database handle.
This is a low-level function intended only for use by implementations
of the AssocCursor
trait. (There is nothing less safe about it being
low-level; it’s simply inconvenient.)
It is an error if txn
is not actually a ReadTransaction
.
sourcepub fn first<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn first<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Positions the cursor at the first key/value pair in the database and returns that pair.
This corresponds to the mdb_cursor_get
function with the
MDB_FIRST
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Germany", "Berlin", f).unwrap();
access.put(&db, "France", "Paris", f).unwrap();
access.put(&db, "Latvia", "Rīga", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("France", "Paris"), cursor.first(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn first_dup<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
pub fn first_dup<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
Positions the cursor at the first key/value pair whose key is equal to the current key, returning the value of that pair.
This only makes sense on DUPSORT
databases.
This correspnods to the mdb_cursor_get
function with the
MDB_FIRST_DUP
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Fruit", "Durian", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Fruit", "Orange"), cursor.last(&access).unwrap());
assert_eq!("Apple", cursor.first_dup::<str>(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn seek_kv<K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + ?Sized>(
&mut self,
key: &K,
val: &V
) -> Result<()>
pub fn seek_kv<K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + ?Sized>(
&mut self,
key: &K,
val: &V
) -> Result<()>
Positions the cursor at the given (key,value) pair.
This only makes sense on DUPSORT
databases.
This corresponds to the mdb_cursor_get
function with the
MDB_GET_BOTH
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Fruit", "Durian", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
cursor.seek_kv("Fruit", "Durian").unwrap();
assert_eq!(("Fruit", "Orange"), cursor.next(&access).unwrap());
assert!(cursor.seek_kv("Fruit", "Lychee").is_err());
}
txn.commit().unwrap();
sourcepub fn seek_k_nearest_v<'access, K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K,
val: &V
) -> Result<&'access V>
pub fn seek_k_nearest_v<'access, K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K,
val: &V
) -> Result<&'access V>
Positions the cursor at the given key and the “nearest” value to val
,
that is, the first (according to sorting) item whose key equals key
and whose value is greater than or equal to val
.
The actual value found is returned.
This only makes sense on DUPSORT
databases.
This corresponds to the mdb_cursor_get
function with the
MDB_GET_BOTH_RANGE
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Fruit", "Banana", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Fruit", "Durian", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!("Durian", cursor.seek_k_nearest_v::<str,str>(
&access, "Fruit", "Durian").unwrap());
assert_eq!("Orange", cursor.seek_k_nearest_v::<str,str>(
&access, "Fruit", "Lychee").unwrap());
assert!(cursor.seek_k_nearest_v::<str,str>(
&access, "Fruit", "Watermelon").is_err());
assert_eq!("Banana", cursor.seek_k_nearest_v::<str,str>(
&access, "Fruit", "Apple").unwrap());
assert!(cursor.seek_k_nearest_v::<str,str>(
&access, "Plant", "Tree").is_err());
}
txn.commit().unwrap();
sourcepub fn get_current<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn get_current<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Returns the current key/value pair under this cursor.
This corresponds to the mdb_cursor_get
function with the
MDB_CURRENT
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Germany", "Berlin", f).unwrap();
access.put(&db, "France", "Paris", f).unwrap();
access.put(&db, "Latvia", "Rīga", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
cursor.seek_k::<str,str>(&access, "Latvia").unwrap();
assert_eq!(("Latvia", "Rīga"), cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn get_multiple<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
pub fn get_multiple<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
Returns as many items as possible with the current key from the current cursor position.
The cursor is advanced so that next_multiple()
returns the next
group of items, if any. Note that this does not return the actual
key (which LMDB itself does not return, contrary to documentation).
The easiest way to use this is for V
to be a slice of LmdbRaw
types.
This only makes sense on DUPSORT
databases with DUPFIXED
set.
This corresponds to the mdb_cursor_get
function with the
MDB_GET_MULTIPLE
operation, except that it does not have a special
case if exactly one value is bound to the key.
See lmdb_zero::db::DUPFIXED
for examples of usage.
sourcepub fn next_multiple<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
pub fn next_multiple<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
Continues fetching items from a cursor positioned by a call to
get_multiple()
.
This corresponds to the mdb_cursor_get
function with the
MDB_NEXT_MULTIPLE
operation.
See lmdb_zero::db::DUPFIXED
for examples of usage.
sourcepub fn last<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn last<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Positions the cursor at the last key/value pair in the database, and returns that pair.
This corresponds to the mdb_cursor_get
function with the
MDB_LAST
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Germany", "Berlin", f).unwrap();
access.put(&db, "France", "Paris", f).unwrap();
access.put(&db, "Latvia", "Rīga", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Latvia", "Rīga"), cursor.last(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn last_dup<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
pub fn last_dup<'access, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<&'access V>
Positions the cursor at the last key/value pair whose key is equal to the current key.
This only makes sense on DUPSORT
databases.
This correspnods to the mdb_cursor_get
function with the
MDB_LAST_DUP
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Fruit", "Durian", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!("Apple", cursor.seek_k::<str,str>(&access, "Fruit").unwrap());
assert_eq!("Orange", cursor.last_dup::<str>(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn next<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn next<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Advances the cursor to the key/value pair following this one.
If the current key has multiple values, this will remain on the same key unless it is already on the last value.
This corresponds to the mdb_cursor_get
function with the
MDB_NEXT
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Animal", "Badger"), cursor.first(&access).unwrap());
assert_eq!(("Fruit", "Apple"), cursor.next(&access).unwrap());
assert_eq!(("Fruit", "Orange"), cursor.next(&access).unwrap());
assert_eq!(("Veggie", "Carrot"), cursor.next(&access).unwrap());
assert!(cursor.next::<str,str>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn next_dup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn next_dup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Advances the cursor to the next value in the current key.
This only makes sense on DUPSORT
databases. This call fails if
there are no more values in the current key.
This corresponds to the mdb_cursor_get
function with the
MDB_NEXT_DUP
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!("Apple", cursor.seek_k::<str,str>(&access, "Fruit").unwrap());
assert_eq!(("Fruit", "Orange"), cursor.next_dup(&access).unwrap());
assert!(cursor.next_dup::<str,str>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn next_nodup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn next_nodup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Advances the cursor to the first item of the key following the current key.
This is permitted in all databases, but only behaves distinctly
from next()
in DUPSORT
databases.
This corresponds to the mdb_cursor_get
function with the
MDB_NEXT_NODUP
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Animal", "Badger"), cursor.first(&access).unwrap());
assert_eq!(("Fruit", "Apple"), cursor.next_nodup(&access).unwrap());
assert_eq!(("Veggie", "Carrot"), cursor.next_nodup(&access).unwrap());
assert!(cursor.next_nodup::<str,str>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn prev<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn prev<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Retreats the cursor to the previous key/value pair.
If the current key has multiple values, this will remain on the same key unless it is already on the first value.
This corresponds to the mdb_cursor_get
function with the
MDB_PREV
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Veggie", "Carrot"), cursor.last(&access).unwrap());
assert_eq!(("Fruit", "Orange"), cursor.prev(&access).unwrap());
assert_eq!(("Fruit", "Apple"), cursor.prev(&access).unwrap());
assert_eq!(("Animal", "Badger"), cursor.prev(&access).unwrap());
assert!(cursor.prev::<str,str>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn prev_dup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn prev_dup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Retreats the cursor to the previous value in the current key.
This only makes sense on DUPSORT
databases. This call fails if
there are no prior values in the current key.
This corresponds to the mdb_cursor_get
function with the
MDB_PREV_DUP
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!("Apple", cursor.seek_k::<str,str>(&access, "Fruit").unwrap());
assert_eq!(("Fruit", "Orange"), cursor.next_dup(&access).unwrap());
assert_eq!(("Fruit", "Apple"), cursor.prev_dup(&access).unwrap());
assert!(cursor.prev_dup::<str,str>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn prev_nodup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
pub fn prev_nodup<'access, K: FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>
) -> Result<(&'access K, &'access V)>
Retreats the cursor to the final item of the previous key.
This is permitted in all databases, but only behaves distinctly
from prev()
in DUPSORT
databases.
This corresponds to the mdb_cursor_get
function with the
MDB_PREV_NODUP
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Veggie", "Carrot"), cursor.last(&access).unwrap());
assert_eq!(("Fruit", "Orange"), cursor.prev_nodup(&access).unwrap());
assert_eq!(("Animal", "Badger"), cursor.prev_nodup(&access).unwrap());
assert!(cursor.prev_nodup::<str,str>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn seek_k<'access, K: AsLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K
) -> Result<&'access V>
pub fn seek_k<'access, K: AsLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K
) -> Result<&'access V>
Positions the cursor at the first item of the given key.
Returns the value of that item.
This corresponds to the mdb_cursor_get
function with the MDB_SET
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!("Apple", cursor.seek_k::<str,str>(&access, "Fruit").unwrap());
}
txn.commit().unwrap();
sourcepub fn seek_k_both<'access, K: AsLmdbBytes + FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K
) -> Result<(&'access K, &'access V)>
pub fn seek_k_both<'access, K: AsLmdbBytes + FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K
) -> Result<(&'access K, &'access V)>
Positions the cursor at the first item of the given key.
Returns the key and value of that item.
This corresponds to the mdb_cursor_get
function with the
MDB_SET_KEY
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
access.put(&db, "Veggie", "Carrot", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Fruit", "Apple"), cursor.seek_k_both(&access, "Fruit").unwrap());
}
txn.commit().unwrap();
sourcepub fn seek_range_k<'access, K: AsLmdbBytes + FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K
) -> Result<(&'access K, &'access V)>
pub fn seek_range_k<'access, K: AsLmdbBytes + FromLmdbBytes + ?Sized, V: FromLmdbBytes + ?Sized>(
&mut self,
access: &'access ConstAccessor<'_>,
key: &K
) -> Result<(&'access K, &'access V)>
Positions the cursor at the first item whose key is greater than or
equal to key
.
Return the key and value of that item.
This corresponds to the mdb_cursor_get
function with the
MDB_SET_RANGE
operation.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
access.put(&db, "Fruit", "Apple", f).unwrap();
access.put(&db, "Fruit", "Orange", f).unwrap();
access.put(&db, "Animal", "Badger", f).unwrap();
let mut cursor = txn.cursor(&db).unwrap();
assert_eq!(("Fruit", "Apple"), cursor.seek_range_k(&access, "Fog").unwrap());
assert!(cursor.seek_range_k::<str,str>(&access, "Veggie").is_err());
}
txn.commit().unwrap();
sourcepub fn put<K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + ?Sized>(
&mut self,
access: &mut WriteAccessor<'_>,
key: &K,
val: &V,
flags: Flags
) -> Result<()>
pub fn put<K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + ?Sized>(
&mut self,
access: &mut WriteAccessor<'_>,
key: &K,
val: &V,
flags: Flags
) -> Result<()>
Writes a single value through this cursor.
By default, any item with the same key (if not DUPSORT
) or any
exactly matching item (if DUPSORT
) is replaced silently. flags
can
be used to override this.
This does not inherently overwrite the current item. See overwrite()
for that.
The cursor is positioned at the new item, or on failure usually near it.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
cursor.put(&mut access, "Germany", "Berlin", f).unwrap();
assert_eq!(("Germany", "Berlin"), cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn overwrite<K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + ?Sized>(
&mut self,
access: &mut WriteAccessor<'_>,
key: &K,
val: &V,
flags: Flags
) -> Result<()>
pub fn overwrite<K: AsLmdbBytes + ?Sized, V: AsLmdbBytes + ?Sized>(
&mut self,
access: &mut WriteAccessor<'_>,
key: &K,
val: &V,
flags: Flags
) -> Result<()>
Overwrites the current item referenced by the cursor.
key
must match the key of the current item. If the database is
DUPSORT
, val
must still sort into the same position relative to the
other items with the same key.
This is intended to be used when the new data is the same size as the old. Otherwise it will simply perform a delete of the old record followed by an insert.
The cursor is positioned at the new item, or on failure usually near it.
Example
use lmdb::unaligned as u;
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
cursor.put(&mut access, "Fourty-two", &42u32, f).unwrap();
cursor.overwrite(&mut access, "Fourty-two", &54u32, f).unwrap();
assert_eq!(("Fourty-two", u(&54u32)),
cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn reserve<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
flags: Flags
) -> Result<&'access mut V>
pub fn reserve<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
flags: Flags
) -> Result<&'access mut V>
Reserves space for an entry with the given key and returns a pointer to that entry.
The size of the entry is simply the size of V
.
This cannot be used on a DUPSORT
database.
The cursor is positioned at the new item, or on failure usually near it.
Example
#[repr(C, packed)]
#[derive(Clone,Copy,Debug,PartialEq,Eq)]
struct MyStruct {
x: i32,
y: i32,
}
unsafe impl lmdb::traits::LmdbRaw for MyStruct { }
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
{
let v: &mut MyStruct = cursor.reserve(&mut access, "foo", f).unwrap();
// Write directly into the database
v.x = 42;
v.y = 56;
}
assert_eq!(("foo", &MyStruct { x: 42, y: 56 }),
cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn reserve_array<'access, K: AsLmdbBytes + ?Sized, V: LmdbRaw>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
count: usize,
flags: Flags
) -> Result<&'access mut [V]>
pub fn reserve_array<'access, K: AsLmdbBytes + ?Sized, V: LmdbRaw>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
count: usize,
flags: Flags
) -> Result<&'access mut [V]>
Reserves space for an entry with the given key and returns a pointer to an array of values backing that entry.
The size of the entry is simply the size of V
times the desired
number of elements.
This cannot be used on a DUPSORT
database. (Do not confuse with
put_multiple
, which does support DUPSORT
but is not zero-copy.)
The cursor is positioned at the new item, or on failure usually near it.
Example
#[repr(C, packed)]
#[derive(Clone,Copy,Debug,PartialEq,Eq)]
struct MyStruct {
x: i32,
y: i32,
}
unsafe impl lmdb::traits::LmdbRaw for MyStruct { }
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
{
let v: &mut [u8] = cursor.reserve_array(&mut access, "foo", 4, f).unwrap();
// Write directly into the database
v[0] = b'b'; v[1] = b'y'; v[2] = b't'; v[3] = b'e';
}
assert_eq!(("foo", "byte"), cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub unsafe fn reserve_unsized<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + ?Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
size: usize,
flags: Flags
) -> Result<&'access mut V>
pub unsafe fn reserve_unsized<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + ?Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
size: usize,
flags: Flags
) -> Result<&'access mut V>
Reserves space for an entry with the given key and returns a pointer to that entry.
This cannot be used on a DUPSORT
database.
The cursor is positioned at the new item, or on failure usually near it.
Unsafety
The caller must ensure that size
is a valid size for V
.
sourcepub fn overwrite_in_place<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
flags: Flags
) -> Result<&'access mut V>
pub fn overwrite_in_place<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
flags: Flags
) -> Result<&'access mut V>
Returns a writable reference to the value belonging to the given key in the database.
This has all the caveats of both overwrite()
and reserve()
.
Updating by mutation
It is possible to use this call to perform a read-modify-write
operation on the data in the database, provided you are certain that
the value exists with the exact size of V
, for example if you just
read the value as a V
using something that requires a particular size
(such as LmdbRaw
).
Example
use lmdb::Unaligned as U;
use lmdb::unaligned as u;
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
cursor.put(&mut access, "count", &1u32, f).unwrap();
{
let count: &mut U<u32> = cursor.overwrite_in_place(
&mut access, "count", f).unwrap();
// Directly edit the value in the database
let count2 = count.get() + 1;
count.set(count2);
}
assert_eq!(("count", u(&2u32)), cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub fn overwrite_in_place_array<'access, K: AsLmdbBytes + ?Sized, V: LmdbRaw>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
count: usize,
flags: Flags
) -> Result<&'access mut [V]>
pub fn overwrite_in_place_array<'access, K: AsLmdbBytes + ?Sized, V: LmdbRaw>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
count: usize,
flags: Flags
) -> Result<&'access mut [V]>
Returns a writable reference to the array of values belonging to the given key in the database.
This has all the caveats of both overwrite()
and reserve_array()
.
Updating by mutation
It is possible to use this call to perform a read-modify-write
operation on the data in the database, provided you are certain that
the value exists with the exact size of V
times count
.
Example
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
cursor.put(&mut access, "foo", "bar", f).unwrap();
{
let data: &mut [u8] = cursor.overwrite_in_place_array(
&mut access, "foo", 3, f).unwrap();
// Directly edit the value in the database
data[2] = b'z';
}
assert_eq!(("foo", "baz"), cursor.get_current(&access).unwrap());
}
txn.commit().unwrap();
sourcepub unsafe fn overwrite_in_place_unsized<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + ?Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
size: usize,
flags: Flags
) -> Result<&'access mut V>
pub unsafe fn overwrite_in_place_unsized<'access, K: AsLmdbBytes + ?Sized, V: FromReservedLmdbBytes + ?Sized>(
&mut self,
access: &'access mut WriteAccessor<'_>,
key: &K,
size: usize,
flags: Flags
) -> Result<&'access mut V>
Returns a writable reference to the value belonging to the given key in the database.
This has all the caveats of both overwrite()
and reserve_unsized()
.
Unsafety
The caller must ensure size
is a valid size of V
.
sourcepub fn put_multiple<K: AsLmdbBytes + ?Sized, V: LmdbRaw>(
&mut self,
access: &mut WriteAccessor<'_>,
key: &K,
values: &[V],
flags: Flags
) -> Result<usize>
pub fn put_multiple<K: AsLmdbBytes + ?Sized, V: LmdbRaw>(
&mut self,
access: &mut WriteAccessor<'_>,
key: &K,
values: &[V],
flags: Flags
) -> Result<usize>
Stores multiple data elements with the same key in a single request.
This is only permitted for DUPFIXED
databases.
Note that values
must be a slice of LmdbRaw
, since this function
needs to know the exact size of each individual item and must be able
to directly reinterpret the slice as a byte array.
On success, returns the number of items that were actually written.
Warning
MDB_MULTIPLE
has historically been rather problematic. Using this
function may result in erratic behaviour on many versions of LMDB.
Example
use lmdb::Unaligned as U;
use lmdb::unaligned as u;
let txn = lmdb::WriteTransaction::new(&env).unwrap();
{
let mut access = txn.access();
let f = lmdb::put::Flags::empty();
let mut cursor = txn.cursor(&db).unwrap();
// XXX Whether this is supposed to be 4 or 3 is unclear.
assert_eq!(4, cursor.put_multiple(
&mut access, "bar", &[U::new(0u32), U::new(1u32),
U::new(2u32), U::new(1u32)], f).unwrap());
assert_eq!(("bar", u(&0u32)), cursor.first(&access).unwrap());
assert_eq!(("bar", u(&1u32)), cursor.next(&access).unwrap());
assert_eq!(("bar", u(&2u32)), cursor.next(&access).unwrap());
assert!(cursor.next::<str,U<u32>>(&access).is_err());
}
txn.commit().unwrap();
sourcepub fn del(
&mut self,
access: &mut WriteAccessor<'_>,
flags: Flags
) -> Result<()>
pub fn del(
&mut self,
access: &mut WriteAccessor<'_>,
flags: Flags
) -> Result<()>
Delete current key/value pair.
By default, this deletes only the current pair. flags
can be set to
NODUPDATA
for DUPDATA
databases to delete everything with the
current key.
See lmdb_zero::del::NODUPDATA
for examples on how flags
can be used
to control behaviour.
Trait Implementations
Auto Trait Implementations
impl<'txn, 'db> !RefUnwindSafe for Cursor<'txn, 'db>
impl<'txn, 'db> !Send for Cursor<'txn, 'db>
impl<'txn, 'db> !Sync for Cursor<'txn, 'db>
impl<'txn, 'db> Unpin for Cursor<'txn, 'db>
impl<'txn, 'db> !UnwindSafe for Cursor<'txn, 'db>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> SafeBorrow<T> for T where
T: ?Sized,
impl<T> SafeBorrow<T> for T where
T: ?Sized,
sourcefn borrow_replacement(ptr: &T) -> &T
fn borrow_replacement(ptr: &T) -> &T
Given ptr
, which was obtained from a prior call to Self::borrow()
,
return a value with the same nominal lifetime which is guaranteed to
survive mutations to Self
. Read more