use std::{future::Future, marker::PhantomData, pin::Pin, sync::Arc};
use crate::secure::{DbConn, DbTx, TxConfig};
use crate::{Db, DbError};
pub struct DBProvider<E> {
db: Arc<Db>,
_error: PhantomData<fn() -> E>,
}
impl<E> Clone for DBProvider<E> {
fn clone(&self) -> Self {
Self {
db: Arc::clone(&self.db),
_error: PhantomData,
}
}
}
impl<E> DBProvider<E>
where
E: From<DbError> + Send + 'static,
{
#[must_use]
pub fn new(db: Db) -> Self {
Self {
db: Arc::new(db),
_error: PhantomData,
}
}
#[must_use]
pub fn db(&self) -> Db {
(*self.db).clone()
}
pub fn conn(&self) -> Result<DbConn<'_>, E> {
self.db.conn().map_err(E::from)
}
pub async fn transaction<T, F>(&self, f: F) -> Result<T, E>
where
T: Send + 'static,
F: for<'a> FnOnce(&'a DbTx<'a>) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'a>>
+ Send,
{
self.db.transaction_ref_mapped(f).await
}
pub async fn transaction_with_config<T, F>(&self, config: TxConfig, f: F) -> Result<T, E>
where
T: Send + 'static,
F: for<'a> FnOnce(&'a DbTx<'a>) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'a>>
+ Send,
{
self.db.transaction_ref_mapped_with_config(config, f).await
}
}