Struct ReadTransaction

Source
pub struct ReadTransaction<'env>(/* private fields */);
Expand description

A read-only LMDB transaction.

In addition to all operations valid on ConstTransaction, a ReadTransaction can additionally operate on cursors with a lifetime scoped to the environment instead of the transaction.

§Ownership

ReadTransactions can be created with all three ownership modes (but owned mode is not useful).

§Example — Shared mode

use std::sync::Arc;

let env = Arc::new(create_env());
let db = Arc::new(lmdb::Database::open(
  env.clone(), None, &lmdb::DatabaseOptions::defaults()).unwrap());

// Type and lifetime annotated explicitly for clarity
let txn: lmdb::ReadTransaction<'static> = lmdb::ReadTransaction::new(
  env.clone()).unwrap();

// Do stuff with `txn`...

§Lifetime

All notes for ConstTransaction apply.

Implementations§

Source§

impl<'env> ReadTransaction<'env>

Source

pub fn new<E>(env: E) -> Result<Self>
where E: Into<NonSyncSupercow<'env, Environment>>,

Opens a new, read-only transaction within the given environment.

§Note

A transaction and its cursors must only be used by a single thread (enforced by the rust compiler), and a thread may only have a single transaction at a time. If NOTLS is in use, this does not apply to read-only transactions. Attempting to open a read-only transaction while the current thread holds a read-write transaction will deadlock.

Source

pub fn dissoc_cursor<'txn, 'db>( &self, cursor: Cursor<'txn, 'db>, ) -> Result<StaleCursor<'db>>
where 'env: 'db,

Dissociates the given cursor from this transaction and its database, returning a StaleCursor which can be reused later.

This only fails if cursor does not belong to this transaction.

§Example
let mut saved_cursor;
{
  let txn = lmdb::ReadTransaction::new(&env).unwrap();
  let cursor = txn.cursor(&db).unwrap();
  // Do some stuff with `txn` and `cursor`

  // We don't want to realloc `cursor` next time, so save it away
  saved_cursor = txn.dissoc_cursor(cursor).unwrap();
} // Read transaction goes away, but our saved cursor remains

{
  let txn = lmdb::ReadTransaction::new(&env).unwrap();
  // Rebind the old cursor. It continues operating on `db`.
  let cursor = txn.assoc_cursor(saved_cursor).unwrap();
  // Do stuff with txn, cursor

  // We can save the cursor away again
  saved_cursor = txn.dissoc_cursor(cursor).unwrap();
}
§Example — Shared ownership mode

Cursors can also be dissociated and reassociated with transactions with shared ownership mode. This can also include changing the ownership mode. To be able to use shared ownership mode, make sure that the AssocCursor trait is imported or else you will simply borrow the inner transaction instead of taking a copy of the Rc, etc.

use std::sync::Arc;

use lmdb::traits::{AssocCursor, CreateCursor};

// N.B. Unnecessary type and lifetime annotations included for clarity
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());

let mut saved_cursor: lmdb::StaleCursor<'static>;
{
  // `Arc` is unnecessary in this trivial example, but let's pretend
  // there was good use for this.
  let txn: Arc<lmdb::ReadTransaction> = Arc::new(
    lmdb::ReadTransaction::new(env.clone()).unwrap());
  let cursor: lmdb::Cursor<'static, 'static> =
    txn.cursor(db.clone()).unwrap();

  // Do some stuff with `txn` and `cursor`

  // We don't want to realloc `cursor` next time, so save it away
  saved_cursor = txn.dissoc_cursor(cursor).unwrap();
}

{
  let txn: Arc<lmdb::ReadTransaction<'static>> =
    Arc::new(lmdb::ReadTransaction::new(env.clone()).unwrap());
  // Rebind the old cursor. It continues operating on `db`.
  let cursor: lmdb::Cursor<'static, 'static> =
    txn.assoc_cursor(saved_cursor).unwrap();
  // Do stuff with txn, cursor

  // We can save the cursor away again
  saved_cursor = txn.dissoc_cursor(cursor).unwrap();
}
Source

pub fn assoc_cursor<'txn, 'db>( &'txn self, cursor: StaleCursor<'db>, ) -> Result<Cursor<'txn, 'db>>

Associates a saved read-only with this transaction.

The cursor will be rebound to this transaction, but will continue using the same database that it was previously.

This method is functionally equivalent to the method on AssocCursor and exists for convenience and backwards-compatibility.

If you have an, e.g., Rc<ReadTransaction> and want to get a Cursor<'static,'db>, make sure you have the AssocCursor trait imported so that the needed alternate implementations of this method are available.

Source

pub fn reset(self) -> ResetTransaction<'env>

Resets this transaction, releasing most of its resources but allowing it to be quickly renewed if desired.

§Example
let mut saved_txn;
{
  let txn = lmdb::ReadTransaction::new(&env).unwrap();
  {
    let access = txn.access();
    // Do stuff with `txn`, `access`
  }
  // Save our transaction so we don't have to reallocate it next time,
  // but we also don't keep locks around and will later move to the
  // latest version of the environment.
  saved_txn = txn.reset();
}

{
  // Instead of creating a brand new transaction, renew the one we
  // saved.
  let txn = saved_txn.renew().unwrap();
  {
    let access = txn.access();
    // Do stuff with `txn`, `access`
  }

  // We can save the transaction away again
  saved_txn = txn.reset();
}

Methods from Deref<Target = ConstTransaction<'env>>§

Source

pub fn access(&self) -> ConstAccessor<'_>

Returns an accessor used to manipulate data in this transaction.

§Ownership

Unlike most other lmdb-zero APIs, accessors do not support shared ownership modes (e.g., where the accessor would hold on to a Rc<ConstTransaction>). If you need dynamically-managed lifetime, instead simply drop the accessor and get a new one the next time one is needed.

§Panics

Panics if this function has already been called on this transaction and the returned value has not yet been dropped.

§Example
let txn = lmdb::ReadTransaction::new(&env).unwrap();
// Get access the first time
let access = txn.access();

// You can't get the accessor again in the same scope, since this
// would create two references to the same logical memory and allow
// creating aliased mutable references and so forth.
let access2 = txn.access(); // PANIC!
Source

pub fn cursor<'txn, 'db, DB>(&'txn self, db: DB) -> Result<Cursor<'txn, 'db>>
where DB: Into<Supercow<'db, Database<'db>>>,

Creates a new cursor scoped to this transaction, bound to the given database.

This method is functionally equivalent to the method on CreateCursor and exists for convenience and backwards-compatibility.

If you have an, e.g., Rc<ReadTransaction> and want to get a Cursor<'static,'db>, make sure you have the CreateCursor trait imported so that the needed alternate implementations of this method are available.

Source

pub fn id(&self) -> usize

Returns the internal id of this transaction.

Source

pub fn db_stat(&self, db: &Database<'_>) -> Result<Stat>

Retrieves statistics for a database.

Source

pub fn db_flags(&self, db: &Database<'_>) -> Result<Flags>

Retrieve the DB flags for a database handle.

Trait Implementations§

Source§

impl<'txn, 'env: 'txn> AssocCursor<'txn> for &'txn ReadTransaction<'env>

Source§

fn assoc_cursor<'db>( &self, cursor: StaleCursor<'db>, ) -> Result<Cursor<'txn, 'db>>

Associates a saved read-only with this transaction. Read more
Source§

impl<'txn, 'env: 'txn> CreateCursor<'txn> for &'txn ReadTransaction<'env>

Source§

fn cursor<'db, DB>(&self, db: DB) -> Result<Cursor<'txn, 'db>>
where DB: Into<Supercow<'db, Database<'db>>>,

Create a cursor using self as the reference to the containing transaction and db as the database the cursor will read from and write into.
Source§

impl<'env> Debug for ReadTransaction<'env>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'env> Deref for ReadTransaction<'env>

Source§

type Target = ConstTransaction<'env>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &ConstTransaction<'env>

Dereferences the value.
Source§

impl<'env> DerefMut for ReadTransaction<'env>

Source§

fn deref_mut(&mut self) -> &mut ConstTransaction<'env>

Mutably dereferences the value.

Auto Trait Implementations§

§

impl<'env> !Freeze for ReadTransaction<'env>

§

impl<'env> !RefUnwindSafe for ReadTransaction<'env>

§

impl<'env> !Send for ReadTransaction<'env>

§

impl<'env> !Sync for ReadTransaction<'env>

§

impl<'env> Unpin for ReadTransaction<'env>

§

impl<'env> !UnwindSafe for ReadTransaction<'env>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> SafeBorrow<T> for T
where T: ?Sized,

Source§

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
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.