Introduce transactions
This commit is contained in:
parent
fdd82b2fef
commit
b01fe7f892
@ -2,7 +2,7 @@ use crate::database::raw::{RawTable, RawTableTryBuilder};
|
||||
use crate::database::wrapped::WrappedTable;
|
||||
use crate::wrapper::{ByteWrapper, ZeroCopyByteWrapper};
|
||||
use anyhow::{ensure, Context};
|
||||
use libmdbx::{DatabaseFlags, Environment, WriteMap};
|
||||
use libmdbx::{DatabaseFlags, Environment, Transaction, TransactionKind, WriteMap, RO, RW};
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -57,4 +57,40 @@ impl Env {
|
||||
v_wrapper,
|
||||
})
|
||||
}
|
||||
|
||||
/// Begins a read-only transaction.
|
||||
pub fn ro_txn(&self) -> anyhow::Result<Txn<RO>> {
|
||||
let mdbx_txn = self.mdbx_env.begin_ro_txn()?;
|
||||
Ok(Txn { mdbx_txn })
|
||||
}
|
||||
|
||||
/// Begins a read-write transaction. This one has an awkward name because `rw_txn` is an easier
|
||||
/// interface (insofar as you don't need to remember to `commit` yourself).
|
||||
pub fn begin_rw_txn(&self) -> anyhow::Result<Txn<RW>> {
|
||||
let mdbx_txn = self.mdbx_env.begin_rw_txn()?;
|
||||
Ok(Txn { mdbx_txn })
|
||||
}
|
||||
|
||||
/// Runs a transaction and commits for you, if the Result variant is `Ok(R)` (NOT `Err`).
|
||||
/// This way, it's hard to forget to commit.
|
||||
pub fn rw_txn<R>(&self, func: impl FnOnce(&Txn<RW>) -> anyhow::Result<R>) -> anyhow::Result<R> {
|
||||
let txn = self.begin_rw_txn()?;
|
||||
let result = func(&txn)?;
|
||||
txn.commit()?;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Txn<'txn, K: TransactionKind> {
|
||||
pub mdbx_txn: Transaction<'txn, K, WriteMap>,
|
||||
}
|
||||
|
||||
impl<'txn, K: TransactionKind> Txn<'txn, K> {}
|
||||
|
||||
impl<'txn> Txn<'txn, RW> {
|
||||
pub fn commit(self) -> anyhow::Result<()> {
|
||||
// TODO bool here, find out what it means and maybe pass up
|
||||
self.mdbx_txn.commit()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub(crate) mod database;
|
||||
pub(crate) mod environment;
|
||||
pub(crate) mod wrapper;
|
||||
pub mod database;
|
||||
pub mod environment;
|
||||
pub mod wrapper;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -2,7 +2,7 @@ use anyhow::anyhow;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use zstd::bulk::{Compressor, Decompressor};
|
||||
|
||||
pub trait ByteWrapper {
|
||||
@ -57,6 +57,18 @@ impl<T: ByteWrapper> ByteWrapper for CompressorWrapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ByteWrapper> ByteWrapper for Arc<T> {
|
||||
type Item = T::Item;
|
||||
|
||||
fn load_from_db_bytes(&self, bytes: &[u8]) -> anyhow::Result<Self::Item> {
|
||||
(&self as &T).load_from_db_bytes(bytes)
|
||||
}
|
||||
|
||||
fn dump_to_db_bytes(&self, item: &Self::Item) -> anyhow::Result<Vec<u8>> {
|
||||
(&self as &T).dump_to_db_bytes(item)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ZeroCopyByteWrapper {
|
||||
fn as_byte_slice(&self) -> &[u8];
|
||||
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self>;
|
||||
|
Loading…
Reference in New Issue
Block a user