use crate::{
table::TableImporter,
transaction::{DbTx, DbTxMut},
DatabaseError,
};
use std::{fmt::Debug, sync::Arc};
pub trait Database: Send + Sync + Debug {
type TX: DbTx + Send + Sync + Debug + 'static;
type TXMut: DbTxMut + DbTx + TableImporter + Send + Sync + Debug + 'static;
#[track_caller]
fn tx(&self) -> Result<Self::TX, DatabaseError>;
#[track_caller]
fn tx_mut(&self) -> Result<Self::TXMut, DatabaseError>;
fn view<T, F>(&self, f: F) -> Result<T, DatabaseError>
where
F: FnOnce(&Self::TX) -> T,
{
let tx = self.tx()?;
let res = f(&tx);
tx.commit()?;
Ok(res)
}
fn update<T, F>(&self, f: F) -> Result<T, DatabaseError>
where
F: FnOnce(&Self::TXMut) -> T,
{
let tx = self.tx_mut()?;
let res = f(&tx);
tx.commit()?;
Ok(res)
}
}
impl<DB: Database> Database for Arc<DB> {
type TX = <DB as Database>::TX;
type TXMut = <DB as Database>::TXMut;
fn tx(&self) -> Result<Self::TX, DatabaseError> {
<DB as Database>::tx(self)
}
fn tx_mut(&self) -> Result<Self::TXMut, DatabaseError> {
<DB as Database>::tx_mut(self)
}
}
impl<DB: Database> Database for &DB {
type TX = <DB as Database>::TX;
type TXMut = <DB as Database>::TXMut;
fn tx(&self) -> Result<Self::TX, DatabaseError> {
<DB as Database>::tx(self)
}
fn tx_mut(&self) -> Result<Self::TXMut, DatabaseError> {
<DB as Database>::tx_mut(self)
}
}