use eventastic::aggregate::Aggregate;
use thiserror::Error;
use crate::{EncryptionProvider, Pickle};
#[allow(type_alias_bounds)]
pub type EventSourcingDbError<E: EncryptionProvider, T: Aggregate> = DbError<
E::Error,
<T::DomainEvent as Pickle>::Error,
<T as Pickle>::Error,
<T::SideEffect as Pickle>::Error,
>;
#[derive(Error, Debug)]
pub enum DbError<
EncryptionError,
EventPicklingError,
SnapshotPicklingError,
SideEffectPicklingError,
> {
#[error("DB Error {0}")]
DbError(sqlx::Error),
#[error("Pickling Error {0}")]
EventPicklingError(EventPicklingError),
#[error("Snapshot Pickling Error {0}")]
SnapshotPicklingError(SnapshotPicklingError),
#[error("Side Effect Pickling Error {0}")]
SideEffectPicklingError(SideEffectPicklingError),
#[error("Invalid Version Number")]
InvalidVersionNumber,
#[error("Invalid Snapshot Version Number")]
InvalidSnapshotVersion,
#[error("Optimistic Concurrency Error")]
OptimisticConcurrencyError,
#[error("Encryption Error {0}")]
Encryption(EncryptionError),
#[error("Encryption provider returned wrong number of items")]
EncryptionProviderReturnedWrongNumberOfItems,
}
#[derive(Error, Debug)]
pub enum SideEffectDbError<EncryptionError, SideEffectPicklingError> {
#[error("DB Error {0}")]
DbError(sqlx::Error),
#[error("Side Effect Pickling Error {0}")]
SideEffectPicklingError(SideEffectPicklingError),
#[error("Encryption Error {0}")]
Encryption(EncryptionError),
#[error("Encryption provider returned wrong number of items")]
EncryptionProviderReturnedWrongNumberOfItems,
}
impl<EP, E, SS, SE> From<sqlx::Error> for DbError<EP, E, SS, SE> {
fn from(e: sqlx::Error) -> Self {
if let Some(db_error) = e.as_database_error() {
if let Some(code) = db_error.code() {
if code == "23505" && db_error.message().contains("aggregate_version") {
return DbError::OptimisticConcurrencyError;
}
}
}
DbError::DbError(e)
}
}
impl<EP, SE> From<sqlx::Error> for SideEffectDbError<EP, SE> {
fn from(e: sqlx::Error) -> Self {
SideEffectDbError::DbError(e)
}
}
impl<EP, E, SS, SE> From<SideEffectDbError<EP, SE>> for DbError<EP, E, SS, SE> {
fn from(e: SideEffectDbError<EP, SE>) -> Self {
match e {
SideEffectDbError::DbError(err) => DbError::DbError(err),
SideEffectDbError::SideEffectPicklingError(err) => {
DbError::SideEffectPicklingError(err)
}
SideEffectDbError::Encryption(err) => DbError::Encryption(err),
SideEffectDbError::EncryptionProviderReturnedWrongNumberOfItems => {
DbError::EncryptionProviderReturnedWrongNumberOfItems
}
}
}
}