Struct ord_lmdb_zero::Database
source · [−]pub struct Database<'a> { /* private fields */ }
Expand description
A handle on an LMDB database within an environment.
Note that in many respects the RAII aspect of this struct is more a matter of convenience than correctness. In particular, if holding a read transaction open, it is possible to obtain a handle to a database created after that transaction started, but this handle will not point to anything within that transaction.
The library does, however, guarantee that there will be at most one
Database
object with the same dbi and environment per process.
Lifetime
A Database
in borrowed mode must be strictly outlived by its
Environment
.
'a
is covariant: given two lifetimes 'x
and 'y
where 'x: 'y
, a
&Database<'x>
will implicitly coerce to &Database<'y>
.
fn convariance<'x, 'y>(db: &lmdb::Database<'x>)
where 'x: 'y {
let _db2: &lmdb::Database<'y> = db;
}
Because of this property, if you need to hold onto an &lmdb::Database
and
must explicitly name both lifetimes, it is usually best to use the same
lifetime for both the reference and the parameter, eg &'x lmdb::Database<'x>
.
Ownership Modes
All three ownership modes are fully supported. Most examples use borrowed
mode, which is used by simply passing an &'env Environment
to open
.
Owned Mode
Owned mode is useful when your application only uses one Database
; this
alleviates the need to track both the Environment
and the Database
.
fn setup() -> lmdb::Database<'static> {
// N.B. Unneeded type and lifetime annotations included for clarity.
let env: lmdb::Environment = create_env();
// Move `env` into the new `Database` because we only want to use the
// default database. Since it owns the `Environment`, its lifetime
// parameter is simply `'static`.
let db: lmdb::Database<'static> = lmdb::Database::open(
env, None, &lmdb::DatabaseOptions::defaults()).unwrap();
// And since it owns the `Environment`, we can even return it without
// worrying about `env`.
db
}
let db = setup();
// Do stuff with `db`...
// When `db` is dropped, so is the inner `Environment`.
Shared Mode
Shared mode allows to have the Database
hold on to the Environment
via
an Arc
instead of a bare reference. This has all the benefits of owned
mode and none of the drawbacks, but makes it harder to determine when
exactly the Environment
gets dropped since this only happens after all
referents are (dynamically) dropped.
Without resorting to unsafe
, shared mode is also the only way to define a
structure which holds both the Environment
itself and its child
Database
values.
use std::sync::Arc;
struct ApplicationContext {
env: Arc<lmdb::Environment>,
// You could of course also put these under `Arc`s as well, for example
// if using shared mode with transactions and/or cursors.
dict: lmdb::Database<'static>,
freq: lmdb::Database<'static>,
}
impl ApplicationContext {
fn into_env(self) -> Arc<lmdb::Environment> { self.env }
}
let env = Arc::new(create_env());
let dict = lmdb::Database::open(
env.clone(), Some("dict"),
&lmdb::DatabaseOptions::create_map::<str>()).unwrap();
let freq = lmdb::Database::open(
env.clone(), Some("freq"),
&lmdb::DatabaseOptions::create_map::<str>()).unwrap();
let context = ApplicationContext {
env: env,
dict: dict,
freq: freq,
};
// Pass `context` around the application freely...
// We could just let `ApplicationContext` drop, but if we want to be
// absolutely sure we know when the `Environment` drops (by panicking if
// it doesn't do so when we want), we can disassemble the struct and check
// manually.
let env = context.into_env(); // Databases get dropped
Arc::try_unwrap(env).unwrap(); // Regain ownership of `Environment`,
// then drop it.
Implementations
sourceimpl<'a> Database<'a>
impl<'a> Database<'a>
sourcepub fn open<E>(
env: E,
name: Option<&str>,
options: &DatabaseOptions
) -> Result<Database<'a>> where
E: Into<Supercow<'a, Environment>>,
pub fn open<E>(
env: E,
name: Option<&str>,
options: &DatabaseOptions
) -> Result<Database<'a>> where
E: Into<Supercow<'a, Environment>>,
Open a database in the environment.
A database handle denotes the name and parameters of a database,
independently of whether such a database exists. The database handle is
implicitly closed when the Database
object is dropped.
To use named databases (with name != None
),
EnvBuilder::set_maxdbs()
must have been called to reserve space for
the extra databases. Database names are keys in the unnamed database,
and may be read but not written.
Transaction-local databases are not supported because the resulting ownership semantics are not expressible in rust. This call implicitly creates a write transaction and uses it to create the database, then commits it on success.
One may not open the same database handle multiple times. Attempting to
do so will result in the Error::Reopened
error.
Beware that if the underlying MDB_env
is being shared (for example,
with native code via Environment::borrow_raw
), using this method to
open a Database
can result in premature closing of the database
handle since the Database
is presumed to own the database handle, but
LMDB will return a shared handle if the database is already open
elsewhere. The disown()
method can be used to
ensure the Database
does not assume ownership of the database
handle.
Examples
Open the default database with default options
{
let db = lmdb::Database::open(
&env, None, &lmdb::DatabaseOptions::defaults()).unwrap();
// Do stuff with `db`
} // The `db` handle is released
Open a named database, creating it if it doesn’t exist
// NOT SHOWN: Call `EnvBuilder::set_maxdbs()` with a value greater than
// one so that there is space for the named database(s).
{
let db = lmdb::Database::open(
&env, Some("example-db"), &lmdb::DatabaseOptions::new(
lmdb::db::CREATE)).unwrap();
// Do stuff with `db`
} // The `db` handle is released
Trying to open the same database more than once
{
let db = lmdb::Database::open(
&env, None, &lmdb::DatabaseOptions::defaults()).unwrap();
// Can't open the same database twice
assert!(lmdb::Database::open(
&env, None, &lmdb::DatabaseOptions::defaults()).is_err());
}
Open a database on a read-only environment
Databases can be opened in read-only environments as long as they already exist.
{
// Succeeds -- The DB already exists
let db = lmdb::Database::open(
&env, None,
&lmdb::DatabaseOptions::new(lmdb::db::Flags::empty())).unwrap();
// Fails -- Can't create a new one in read-only mode
assert!(lmdb::Database::open(
&env, Some("name"),
&lmdb::DatabaseOptions::new(lmdb::db::CREATE)).is_err());
}
sourcepub unsafe fn from_raw<E>(env: E, raw: MDB_dbi) -> Self where
E: Into<Supercow<'a, Environment>>,
pub unsafe fn from_raw<E>(env: E, raw: MDB_dbi) -> Self where
E: Into<Supercow<'a, Environment>>,
Wrap a raw MDB_dbi
associated with this environment.
This call assumes ownership of the MDB_dbi
, and the resulting
Database
will close it on drop. If this is not desired, see
borrow_raw()
instead.
Unsafety
raw
must reference a database currently open in env
.
The caller must ensure that nothing closes the handle until
into_raw()
is called and that nothing uses it after the Database
is
dropped normally.
Panics
Panics if raw
is a handle already owned by env
.
sourcepub unsafe fn borrow_raw<E>(env: E, raw: MDB_dbi) -> Self where
E: Into<Supercow<'a, Environment>>,
pub unsafe fn borrow_raw<E>(env: E, raw: MDB_dbi) -> Self where
E: Into<Supercow<'a, Environment>>,
Wrap a raw MDB_dbi
associated with this environment without taking
ownership.
This call does not assume ownership of raw
, and as a result neither
checks whether any other Database
s exist with the same handle, nor
records this particular handle in env
’s list of owned databases.
Unsafety
raw
must reference a database currently open in env
.
The caller must ensure that nothing closes the handle until the
resulting Database
is dropped.
sourcepub fn delete(self) -> Result<()>
pub fn delete(self) -> Result<()>
Deletes this database.
This call implicitly creates a new write transaction to perform the operation, so that the lifetime of the database handle does not depend on the outcome. The database handle is closed implicitly by this operation.
Note that the other mdb_drop
operation which simply clears the
database is exposed through WriteAccessor
and is transactional.
Example
// NOT SHOWN: Call `EnvBuilder::set_maxdbs()` with a value greater than
// one so that there is space for the named database(s).
{
let db = lmdb::Database::open(
&env, Some("example-db"), &lmdb::DatabaseOptions::new(
lmdb::db::CREATE)).unwrap();
// Do stuff with `db`
// Delete the database itself. This also consumes `db`.
db.delete().unwrap();
// We can now recreate the database if we so desire.
// Note that you should not use delete+open to clear a database; use
// `WriteAccessor::clear_db()` to do that.
let db = lmdb::Database::open(
&env, Some("example-db"), &lmdb::DatabaseOptions::new(
lmdb::db::CREATE)).unwrap();
}
sourcepub fn env(&self) -> &Environment
pub fn env(&self) -> &Environment
Returns a reference to the Environment
to which this Database
belongs.
This can be used to elide needing to pass both an &Environment
and an
&Database
around, but is also useful for the use-case wherein the
Database
owns the Environment
.
Because this may borrow an Environment
owned by this Database
, the
lifetime of the returned reference is dependent on self rather than
being 'env
. (In fact, 'env
is usually 'static
if the
Environment
is owned by the Database
, so returning &'env Environment
is impossible anyway.)
Example
let env: lmdb::Environment = create_env();
// We only want one `Database`, so don't bother keeping both variables
// around and instead let the `Database` own the `Environment`.
let db = lmdb::Database::open(
env, None, &lmdb::DatabaseOptions::defaults()).unwrap();
// `env` has been consumed, but we can still do useful things by
// getting a reference to the inner value.
let txn = lmdb::ReadTransaction::new(db.env()).unwrap();
// Do stuff with `txn`, etc.
sourcepub fn assert_same_env(&self, other_env: &Environment) -> Result<()>
pub fn assert_same_env(&self, other_env: &Environment) -> Result<()>
Checks that other_env
is the same as the environment on this
Database
.
If it matches, returns Ok(())
; otherwise, returns Err
.
sourcepub fn dbi(&self) -> MDB_dbi
👎 Deprecated since 0.4.4: use as_raw() instead
pub fn dbi(&self) -> MDB_dbi
use as_raw() instead
Returns the underlying integer handle for this database.
Deprecated
Renamed to as_raw()
for consistency.
Trait Implementations
Auto Trait Implementations
impl<'a> !RefUnwindSafe for Database<'a>
impl<'a> Send for Database<'a>
impl<'a> Sync for Database<'a>
impl<'a> Unpin for Database<'a>
impl<'a> !UnwindSafe for Database<'a>
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