use crate::{ table::TableImporter, transaction::{DbTx, DbTxMut}, DatabaseError, }; use std::{fmt::Debug, sync::Arc}; /// Main Database trait that can open read-only and read-write transactions. /// /// Sealed trait which cannot be implemented by 3rd parties, exposed only for consumption. pub trait Database: Send + Sync { /// Read-Only database transaction type TX: DbTx + Send + Sync + Debug + 'static; /// Read-Write database transaction type TXMut: DbTxMut + DbTx + TableImporter + Send + Sync + Debug + 'static; /// Create read only transaction. #[track_caller] fn tx(&self) -> Result; /// Create read write transaction only possible if database is open with write access. #[track_caller] fn tx_mut(&self) -> Result; /// Takes a function and passes a read-only transaction into it, making sure it's closed in the /// end of the execution. fn view(&self, f: F) -> Result where F: FnOnce(&Self::TX) -> T, { let tx = self.tx()?; let res = f(&tx); tx.commit()?; Ok(res) } /// Takes a function and passes a write-read transaction into it, making sure it's committed in /// the end of the execution. fn update(&self, f: F) -> Result where F: FnOnce(&Self::TXMut) -> T, { let tx = self.tx_mut()?; let res = f(&tx); tx.commit()?; Ok(res) } } impl Database for Arc { type TX = ::TX; type TXMut = ::TXMut; fn tx(&self) -> Result { ::tx(self) } fn tx_mut(&self) -> Result { ::tx_mut(self) } } impl Database for &DB { type TX = ::TX; type TXMut = ::TXMut; fn tx(&self) -> Result { ::tx(self) } fn tx_mut(&self) -> Result { ::tx_mut(self) } }