use std::sync::Arc;
use crate::database::{
CompareAndSwapTransaction, Createable, CustomTransactionError, DatabaseEntry, DbHandle,
Deleteable, EntryId, Mergeable, TransactionError, caching::Cacheable, db_transaction,
};
pub trait EntryExtensions: DatabaseEntry {
fn db_upsert(self, db: DbHandle<Self::Db>) -> Result<(), TransactionError> {
db_transaction(
|cas_tx| {
cas_tx.tx_upsert(self.clone())?;
Ok(())
},
db,
false,
)?;
Ok(())
}
fn db_insert(self, db: DbHandle<Self::Db>) -> Result<(), TransactionError> {
db_transaction(
|cas_tx| {
cas_tx.tx_upsert(self.clone())?;
Ok(())
},
db,
false,
)?;
Ok(())
}
fn db_merge(self, from: Self, db: DbHandle<Self::Db>) -> Result<Self, TransactionError>
where
Self: Mergeable,
{
let new = db_transaction(
|cas_tx| {
let item = cas_tx.tx_merge(self.clone(), from.clone())?;
Ok(item)
},
db,
false,
)?;
Ok(new)
}
fn db_patch(self, db: DbHandle<Self::Db>) -> Result<Self, TransactionError>
where
Self: Mergeable,
{
let new = db_transaction(
|cas_tx| {
let item = cas_tx.tx_patch(self.clone())?;
Ok(item)
},
db,
false,
)?;
Ok(new)
}
fn db_merge_batch(
self,
from: impl IntoIterator<Item = Self> + Clone,
db: DbHandle<Self::Db>,
) -> Result<Self, TransactionError>
where
Self: Mergeable,
{
let new = db_transaction(
|cas_tx| {
let item = cas_tx.tx_merge_batch(self.clone(), from.clone())?;
Ok(item)
},
db,
false,
)?;
Ok(new)
}
fn db_delete(&mut self, item: Self, db: DbHandle<Self::Db>) -> Result<(), TransactionError>
where
Self: Deleteable,
{
db_transaction(
|cas_tx| {
cas_tx.tx_delete(item.clone())?;
Ok(())
},
db,
false,
)?;
Ok(())
}
fn db_delete_id<Id>(id: Self::Id, db: DbHandle<Self::Db>) -> Result<(), TransactionError>
where
Self: Deleteable,
{
db_transaction(
|cas_tx| {
cas_tx.tx_delete_id(id)?;
Ok(())
},
db,
false,
)?;
Ok(())
}
fn db_create(
args: <Self as Createable>::CreateArgs,
db: DbHandle<Self::Db>,
) -> Result<Self, CustomTransactionError<<Self as Createable>::Err>>
where
Self: Createable,
{
let new = db_transaction(|cas_tx| cas_tx.tx_create(args.clone()), db, false)?;
Ok(new)
}
}
impl<T: DatabaseEntry> EntryExtensions for T {}
pub trait EntryIdExt: EntryId
where
Self::Entry: DatabaseEntry<Id = Self, Db = Self::IdDb>,
{
fn db_get(self, db: &Self::IdDb) -> Result<Option<Self::Entry>, TransactionError> {
Self::Entry::db_get(self, db)
}
fn tx_get(
self,
cas_tx: &CompareAndSwapTransaction<Self::IdDb>,
) -> Result<Option<Self::Entry>, TransactionError> {
cas_tx.tx_get(self)
}
fn cache_get(self, db: &Self::IdDb) -> Result<Option<Arc<Self::Entry>>, TransactionError>
where
Self::Entry: Cacheable,
{
Self::Entry::cache_get(self, db)
}
}
impl<T: EntryId> EntryIdExt for T where Self::Entry: DatabaseEntry<Id = Self, Db = Self::IdDb> {}
pub trait EntryIdIteratorExt<Id: EntryId>: IntoIterator<Item = Id> + Sized
where
Id::Entry: DatabaseEntry<Db = Id::IdDb, Id = Id>,
{
fn db_get_batch(self, db: &Id::IdDb) -> Result<Vec<Id::Entry>, TransactionError> {
Id::Entry::db_get_batch(self, db)
}
fn tx_get_batch(
self,
cas_tx: &CompareAndSwapTransaction<Id::IdDb>,
) -> Result<Vec<Id::Entry>, TransactionError> {
cas_tx.tx_get_batch(self)
}
fn cache_get_batch(self, db: &Id::IdDb) -> Result<Vec<Arc<Id::Entry>>, TransactionError>
where
Id::Entry: Cacheable,
{
Id::Entry::cache_get_batch(self, db)
}
}
impl<Id: EntryId, T: IntoIterator<Item = Id>> EntryIdIteratorExt<Id> for T where
Id::Entry: DatabaseEntry<Db = Id::IdDb, Id = Id>
{
}