use diesel::{
connection::TransactionManager,
r2d2::{ConnectionManager, Pool, PooledConnection},
sqlite::SqliteConnection,
Connection,
};
#[cfg(feature = "batch-store")]
use crate::batches::store::{BatchStore, DieselBatchStore, DieselConnectionBatchStore};
use crate::commits::store::{CommitStore, DieselCommitStore, DieselConnectionCommitStore};
use crate::error::InternalError;
#[cfg(feature = "location")]
use crate::location::store::{DieselConnectionLocationStore, DieselLocationStore, LocationStore};
#[cfg(feature = "pike")]
use crate::pike::store::{DieselConnectionPikeStore, DieselPikeStore, PikeStore};
#[cfg(feature = "product")]
use crate::product::store::{DieselConnectionProductStore, DieselProductStore, ProductStore};
#[cfg(feature = "purchase-order")]
use crate::purchase_order::store::{
DieselConnectionPurchaseOrderStore, DieselPurchaseOrderStore, PurchaseOrderStore,
};
#[cfg(feature = "schema")]
use crate::schema::store::{DieselConnectionSchemaStore, DieselSchemaStore, SchemaStore};
#[cfg(feature = "track-and-trace")]
use crate::track_and_trace::store::{
DieselConnectionTrackAndTraceStore, DieselTrackAndTraceStore, TrackAndTraceStore,
};
use super::{InContextStoreFactory, StoreFactory, TransactionalStoreFactory};
#[derive(Clone)]
pub struct SqliteStoreFactory {
pool: Pool<ConnectionManager<SqliteConnection>>,
}
impl<'a> SqliteStoreFactory {
pub fn new(pool: Pool<ConnectionManager<SqliteConnection>>) -> Self {
Self { pool }
}
}
impl StoreFactory for SqliteStoreFactory {
fn get_grid_commit_store<'a>(&'a self) -> Box<dyn CommitStore + 'a> {
Box::new(DieselCommitStore::new(self.pool.clone()))
}
#[cfg(feature = "pike")]
fn get_grid_pike_store<'a>(&'a self) -> Box<dyn PikeStore + 'a> {
Box::new(DieselPikeStore::new(self.pool.clone()))
}
#[cfg(feature = "location")]
fn get_grid_location_store<'a>(&'a self) -> Box<dyn LocationStore + 'a> {
Box::new(DieselLocationStore::new(self.pool.clone()))
}
#[cfg(feature = "product")]
fn get_grid_product_store<'a>(&'a self) -> Box<dyn ProductStore + 'a> {
Box::new(DieselProductStore::new(self.pool.clone()))
}
#[cfg(feature = "schema")]
fn get_grid_schema_store<'a>(&'a self) -> Box<dyn SchemaStore + 'a> {
Box::new(DieselSchemaStore::new(self.pool.clone()))
}
#[cfg(feature = "track-and-trace")]
fn get_grid_track_and_trace_store<'a>(&'a self) -> Box<dyn TrackAndTraceStore + 'a> {
Box::new(DieselTrackAndTraceStore::new(self.pool.clone()))
}
#[cfg(feature = "batch-store")]
fn get_batch_store<'a>(&'a self) -> Box<dyn BatchStore + 'a> {
Box::new(DieselBatchStore::new(self.pool.clone()))
}
#[cfg(feature = "purchase-order")]
fn get_grid_purchase_order_store<'a>(&'a self) -> Box<dyn PurchaseOrderStore + 'a> {
Box::new(DieselPurchaseOrderStore::new(self.pool.clone()))
}
}
impl TransactionalStoreFactory for SqliteStoreFactory {
fn begin_transaction<'a>(&self) -> Result<Box<dyn InContextStoreFactory<'a>>, InternalError> {
let conn = self
.pool
.get()
.map_err(|err| InternalError::from_source(Box::new(err)))?;
let store_factory = InContextSqliteStoreFactory::new(conn);
store_factory
.conn
.transaction_manager()
.begin_transaction(&store_factory.conn)
.map_err(|err| InternalError::from_source(Box::new(err)))?;
Ok(Box::new(store_factory))
}
fn clone_box(&self) -> Box<dyn TransactionalStoreFactory> {
Box::new(self.clone())
}
}
pub struct InContextSqliteStoreFactory {
conn: PooledConnection<ConnectionManager<SqliteConnection>>,
}
impl InContextSqliteStoreFactory {
fn new(conn: PooledConnection<ConnectionManager<SqliteConnection>>) -> Self {
Self { conn }
}
}
impl StoreFactory for InContextSqliteStoreFactory {
fn get_grid_commit_store<'a>(&'a self) -> Box<dyn CommitStore + 'a> {
Box::new(DieselConnectionCommitStore::new(&*self.conn))
}
#[cfg(feature = "pike")]
fn get_grid_pike_store<'a>(&'a self) -> Box<dyn PikeStore + 'a> {
Box::new(DieselConnectionPikeStore::new(&*self.conn))
}
#[cfg(feature = "location")]
fn get_grid_location_store<'a>(&'a self) -> Box<dyn LocationStore + 'a> {
Box::new(DieselConnectionLocationStore::new(&*self.conn))
}
#[cfg(feature = "product")]
fn get_grid_product_store<'a>(&'a self) -> Box<dyn ProductStore + 'a> {
Box::new(DieselConnectionProductStore::new(&*self.conn))
}
#[cfg(feature = "schema")]
fn get_grid_schema_store<'a>(&'a self) -> Box<dyn SchemaStore + 'a> {
Box::new(DieselConnectionSchemaStore::new(&*self.conn))
}
#[cfg(feature = "track-and-trace")]
fn get_grid_track_and_trace_store<'a>(&'a self) -> Box<dyn TrackAndTraceStore + 'a> {
Box::new(DieselConnectionTrackAndTraceStore::new(&*self.conn))
}
#[cfg(feature = "batch-store")]
fn get_batch_store<'a>(&'a self) -> Box<dyn BatchStore + 'a> {
Box::new(DieselConnectionBatchStore::new(&*self.conn))
}
#[cfg(feature = "purchase-order")]
fn get_grid_purchase_order_store<'a>(&'a self) -> Box<dyn PurchaseOrderStore + 'a> {
Box::new(DieselConnectionPurchaseOrderStore::new(&*self.conn))
}
}
impl<'a> InContextStoreFactory<'a> for InContextSqliteStoreFactory {
fn commit(&self) -> Result<(), InternalError> {
let transaction_manager = self.conn.transaction_manager();
transaction_manager
.commit_transaction(&*self.conn)
.map_err(|err| InternalError::from_source(Box::new(err)))?;
Ok(())
}
fn rollback(&self) -> Result<(), InternalError> {
let transaction_manager = self.conn.transaction_manager();
transaction_manager
.rollback_transaction(&*self.conn)
.map_err(|err| InternalError::from_source(Box::new(err)))?;
Ok(())
}
}