aingle_lmdb/
lib.rs

1//! Idiomatic and safe APIs for interacting with the
2//! [Lightning Memory-mapped Database (LMDB)](https://symas.com/lmdb).
3
4#![deny(missing_docs)]
5#![doc(html_root_url = "https://docs.rs/lmdb-rkv/0.14.1")]
6
7use aingle_lmdb_sys as ffi;
8
9pub use crate::cursor::{
10    Cursor,
11    Iter,
12    IterDup,
13    RoCursor,
14    RwCursor,
15};
16pub use crate::database::Database;
17pub use crate::environment::{
18    Environment,
19    EnvironmentBuilder,
20    Info,
21    Stat,
22};
23pub use crate::error::{
24    Error,
25    Result,
26};
27pub use crate::flags::*;
28pub use crate::transaction::{
29    InactiveTransaction,
30    RoTransaction,
31    RwTransaction,
32    Transaction,
33};
34
35macro_rules! lmdb_try {
36    ($expr:expr) => {{
37        match $expr {
38            ffi::MDB_SUCCESS => (),
39            err_code => return Err(crate::Error::from_err_code(err_code)),
40        }
41    }};
42}
43
44macro_rules! lmdb_try_with_cleanup {
45    ($expr:expr, $cleanup:expr) => {{
46        match $expr {
47            ffi::MDB_SUCCESS => (),
48            err_code => {
49                let _ = $cleanup;
50                return Err(crate::Error::from_err_code(err_code));
51            },
52        }
53    }};
54}
55
56mod cursor;
57mod database;
58mod environment;
59mod error;
60mod flags;
61mod transaction;
62
63#[cfg(test)]
64mod test_utils {
65
66    use byteorder::{
67        ByteOrder,
68        LittleEndian,
69    };
70
71    use super::*;
72
73    /// Regression test for https://github.com/danburkert/lmdb-rs/issues/21.
74    /// This test reliably segfaults when run against lmbdb compiled with opt level -O3 and newer
75    /// GCC compilers.
76    #[test]
77    fn issue_21_regression() {
78        const HEIGHT_KEY: [u8; 1] = [0];
79
80        let dir = tempfile::tempdir().unwrap();
81
82        let env = {
83            let mut builder = Environment::new();
84            builder.set_max_dbs(2);
85            builder.set_map_size(1_000_000);
86            builder.open(dir.path()).expect("open lmdb env")
87        };
88        let index = env.create_db(None, DatabaseFlags::DUP_SORT).expect("open index db");
89
90        for height in 0..1000 {
91            let mut value = [0u8; 8];
92            LittleEndian::write_u64(&mut value, height);
93            let mut tx = env.begin_rw_txn().expect("begin_rw_txn");
94            tx.put(index, &HEIGHT_KEY, &value, WriteFlags::empty()).expect("tx.put");
95            tx.commit().expect("tx.commit")
96        }
97    }
98}