1#![doc(
2 html_favicon_url = "https://raw.githubusercontent.com/meilisearch/heed/main/assets/heed-pigeon.ico?raw=true"
3)]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/meilisearch/heed/main/assets/heed-pigeon-logo.png?raw=true"
6)]
7
8#![warn(missing_docs)]
64
65pub mod cookbook;
66mod cursor;
67mod database;
68mod env;
69pub mod iteration_method;
70mod iterator;
71mod mdb;
72mod reserved_space;
73mod txn;
74
75use std::ffi::CStr;
76use std::{error, fmt, io, mem, result};
77
78use heed_traits as traits;
79pub use {byteorder, heed_types as types};
80
81use self::cursor::{RoCursor, RwCursor};
82pub use self::database::{Database, DatabaseOpenOptions, DatabaseStat};
83pub use self::env::{
84 env_closing_event, CompactionOption, DefaultComparator, Env, EnvClosingEvent, EnvInfo,
85 EnvOpenOptions, FlagSetMode,
86};
87pub use self::iterator::{
88 RoIter, RoPrefix, RoRange, RoRevIter, RoRevPrefix, RoRevRange, RwIter, RwPrefix, RwRange,
89 RwRevIter, RwRevPrefix, RwRevRange,
90};
91pub use self::mdb::error::Error as MdbError;
92use self::mdb::ffi::{from_val, into_val};
93pub use self::mdb::flags::{DatabaseFlags, EnvFlags, PutFlags};
94pub use self::reserved_space::ReservedSpace;
95pub use self::traits::{BoxedError, BytesDecode, BytesEncode, Comparator, LexicographicComparator};
96pub use self::txn::{RoTxn, RwTxn};
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
100pub struct LmdbVersion {
101 pub string: &'static str,
103 pub major: i32,
105 pub minor: i32,
107 pub patch: i32,
109}
110
111pub fn lmdb_version() -> LmdbVersion {
125 let mut major = mem::MaybeUninit::uninit();
126 let mut minor = mem::MaybeUninit::uninit();
127 let mut patch = mem::MaybeUninit::uninit();
128
129 unsafe {
130 let string_ptr =
131 mdb::ffi::mdb_version(major.as_mut_ptr(), minor.as_mut_ptr(), patch.as_mut_ptr());
132 LmdbVersion {
133 string: CStr::from_ptr(string_ptr).to_str().unwrap(),
134 major: major.assume_init(),
135 minor: minor.assume_init(),
136 patch: patch.assume_init(),
137 }
138 }
139}
140
141#[derive(Debug)]
143pub enum Error {
144 Io(io::Error),
146 Mdb(MdbError),
148 Encoding(BoxedError),
150 Decoding(BoxedError),
152 DatabaseClosing,
154 BadOpenOptions {
156 options: EnvOpenOptions,
158 env: Env,
160 },
161}
162
163impl fmt::Display for Error {
164 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165 match self {
166 Error::Io(error) => write!(f, "{}", error),
167 Error::Mdb(error) => write!(f, "{}", error),
168 Error::Encoding(error) => write!(f, "error while encoding: {}", error),
169 Error::Decoding(error) => write!(f, "error while decoding: {}", error),
170 Error::DatabaseClosing => {
171 f.write_str("database is in a closing phase, you can't open it at the same time")
172 }
173 Error::BadOpenOptions { .. } => {
174 f.write_str("an environment is already opened with different options")
175 }
176 }
177 }
178}
179
180impl error::Error for Error {}
181
182impl From<MdbError> for Error {
183 fn from(error: MdbError) -> Error {
184 match error {
185 MdbError::Other(e) => Error::Io(io::Error::from_raw_os_error(e)),
186 _ => Error::Mdb(error),
187 }
188 }
189}
190
191impl From<io::Error> for Error {
192 fn from(error: io::Error) -> Error {
193 Error::Io(error)
194 }
195}
196
197pub type Result<T> = result::Result<T, Error>;
199
200pub enum Unspecified {}
207
208macro_rules! assert_eq_env_db_txn {
209 ($database:ident, $txn:ident) => {
210 assert!(
211 $database.env_ident == $txn.env_mut_ptr() as usize,
212 "The database environment doesn't match the transaction's environment"
213 );
214 };
215}
216
217macro_rules! assert_eq_env_txn {
218 ($env:expr, $txn:ident) => {
219 assert!(
220 $env.env_mut_ptr() == $txn.env_mut_ptr(),
221 "The environment doesn't match the transaction's environment"
222 );
223 };
224}
225
226pub(crate) use {assert_eq_env_db_txn, assert_eq_env_txn};
227
228#[cfg(test)]
229mod tests {
230 use super::*;
231
232 #[test]
233 fn error_is_send_sync() {
234 fn give_me_send_sync<T: Send + Sync>(_: T) {}
235
236 let error = Error::Encoding(Box::from("There is an issue, you know?"));
237 give_me_send_sync(error);
238 }
239}