#[cfg(test)]
extern crate tempfile;
use error::Wrap;
pub use error::{Error, Result};
use ffi::{unqlite_close, unqlite_open};
use std::ffi::CString;
use std::mem;
use std::ptr::NonNull;
pub struct UnQLite {
engine: NonNull<crate::ffi::unqlite>,
}
macro_rules! eval {
($i: ident, $($e: expr),*) => (
loop {
match unsafe {
paste::expr! { [<unqlite_ $i>]($($e),*) }
} {
crate::vars::UNQLITE_LOCKED => {},
state => break state
}
}
);
}
macro_rules! wrap {
($i: ident, $($e: expr),*) => (eval!($i, $($e),*).wrap());
}
macro_rules! wrap_raw {
($self_:ident, $i: ident) => (
wrap!($i, $self_.as_raw_mut_ptr())
);
($self_:ident, $i: ident, $($e: expr),+) => (
wrap!($i, $self_.as_raw_mut_ptr(), $($e),+)
);
}
impl UnQLite {
#[inline]
fn open<P: AsRef<str>>(filename: P, mode: OpenMode) -> Result<UnQLite> {
let mut db: *mut crate::ffi::unqlite = unsafe { mem::MaybeUninit::uninit().assume_init() };
let filename = filename.as_ref();
let filename = CString::new(filename)?;
wrap!(open, &mut db, filename.as_ptr(), mode.into()).map(|_| UnQLite {
engine: unsafe { NonNull::new_unchecked(db) },
})
}
#[inline]
pub fn create<P: AsRef<str>>(filename: P) -> UnQLite {
Self::open(filename, OpenMode::Create).unwrap()
}
#[inline]
pub fn create_in_memory() -> UnQLite {
Self::create(":mem:")
}
#[inline]
pub fn create_temp() -> UnQLite {
Self::open("", OpenMode::TempDB).unwrap()
}
#[inline]
pub fn open_mmap<P: AsRef<str>>(filename: P) -> UnQLite {
Self::open(filename, OpenMode::MMap).unwrap()
}
#[inline]
pub fn open_readonly<P: AsRef<str>>(filename: P) -> UnQLite {
Self::open(filename, OpenMode::ReadOnly).unwrap()
}
fn close(&self) -> Result<()> {
wrap!(close, self.as_raw_mut_ptr())
}
unsafe fn as_raw_mut_ptr(&self) -> *mut crate::ffi::unqlite {
self.engine.as_ptr()
}
}
unsafe impl Send for UnQLite {}
unsafe impl Sync for UnQLite {}
impl Drop for UnQLite {
fn drop(&mut self) {
self.close().unwrap();
}
}
#[allow(dead_code, non_snake_case, non_camel_case_types)]
pub mod ffi;
#[allow(dead_code)]
pub mod vars;
mod config;
pub mod document;
mod error;
mod kv_cursor;
mod kv_store;
mod openmode;
mod transaction;
mod util;
pub use self::config::Config;
pub use self::kv_cursor::*;
pub use self::kv_store::*;
use self::openmode::OpenMode;
pub use self::transaction::Transaction;
pub use self::util::*;
#[cfg(test)]
#[cfg(feature = "enable-threads")]
mod tests_threadsafe {
use super::UnQLite;
#[test]
fn create_temp() {
let _ = UnQLite::create_temp();
}
#[test]
fn create_in_memory() {
let _ = UnQLite::create_in_memory();
}
#[test]
fn from_readonly_memory() {
let _ = UnQLite::open_readonly(":mem:");
}
}
#[cfg(test)]
mod tests {
use super::UnQLite;
#[test]
fn open() {
let _ = UnQLite::create_temp();
let _ = UnQLite::create_in_memory();
let _ = UnQLite::open_readonly(":mem:");
}
}