pub mod accounts;
mod cache;
pub mod channels;
pub mod db;
pub mod errors;
pub mod info;
pub mod logs;
pub mod peers;
pub mod protocol;
pub mod registry;
pub mod resolver;
mod ticket_manager;
pub mod tickets;
pub use hopr_db_api as api;
pub use sea_orm::DatabaseConnection;
pub use sea_orm::DatabaseTransaction;
use crate::accounts::HoprDbAccountOperations;
use crate::channels::HoprDbChannelOperations;
use async_trait::async_trait;
use futures::future::BoxFuture;
use sea_orm::TransactionTrait;
use crate::db::HoprDb;
use crate::errors::{DbSqlError, Result};
use crate::info::HoprDbInfoOperations;
use crate::registry::HoprDbRegistryOperations;
use hopr_db_api::logs::HoprDbLogOperations;
use hopr_db_api::peers::HoprDbPeersOperations;
use hopr_db_api::protocol::HoprDbProtocolOperations;
use hopr_db_api::resolver::HoprDbResolverOperations;
use hopr_db_api::tickets::HoprDbTicketOperations;
pub const SINGULAR_TABLE_FIXED_ID: i32 = 1;
pub type DbTimestamp = chrono::DateTime<chrono::Utc>;
#[derive(Debug)]
pub struct OpenTransaction(DatabaseTransaction, TargetDb);
impl OpenTransaction {
pub async fn perform<F, T, E>(self, callback: F) -> std::result::Result<T, E>
where
F: for<'c> FnOnce(&'c OpenTransaction) -> BoxFuture<'c, std::result::Result<T, E>> + Send,
T: Send,
E: std::error::Error + From<DbSqlError>,
{
let res = callback(&self).await;
if res.is_ok() {
self.commit().await?;
} else {
self.rollback().await?;
}
res
}
pub async fn commit(self) -> Result<()> {
Ok(self.0.commit().await?)
}
pub async fn rollback(self) -> Result<()> {
Ok(self.0.rollback().await?)
}
}
impl AsRef<DatabaseTransaction> for OpenTransaction {
fn as_ref(&self) -> &DatabaseTransaction {
&self.0
}
}
impl From<OpenTransaction> for DatabaseTransaction {
fn from(value: OpenTransaction) -> Self {
value.0
}
}
pub type OptTx<'a> = Option<&'a OpenTransaction>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
pub enum TargetDb {
#[default]
Index,
Tickets,
Peers,
Logs,
}
#[async_trait]
pub trait HoprDbGeneralModelOperations {
fn conn(&self, target_db: TargetDb) -> &DatabaseConnection;
async fn begin_transaction_in_db(&self, target: TargetDb) -> Result<OpenTransaction>;
async fn begin_transaction(&self) -> Result<OpenTransaction> {
self.begin_transaction_in_db(Default::default()).await
}
async fn nest_transaction_in_db(&self, tx: OptTx<'_>, target_db: TargetDb) -> Result<OpenTransaction> {
if let Some(t) = tx {
assert_eq!(t.1, target_db, "attempt to create nest into tx from a different db");
Ok(OpenTransaction(t.as_ref().begin().await?, target_db))
} else {
self.begin_transaction_in_db(target_db).await
}
}
async fn nest_transaction(&self, tx: OptTx<'_>) -> Result<OpenTransaction> {
self.nest_transaction_in_db(tx, Default::default()).await
}
}
#[async_trait]
impl HoprDbGeneralModelOperations for HoprDb {
fn conn(&self, target_db: TargetDb) -> &DatabaseConnection {
match target_db {
TargetDb::Index => &self.index_db,
TargetDb::Tickets => &self.tickets_db,
TargetDb::Peers => &self.peers_db,
TargetDb::Logs => &self.logs_db,
}
}
async fn begin_transaction_in_db(&self, target_db: TargetDb) -> Result<OpenTransaction> {
match target_db {
TargetDb::Index => Ok(OpenTransaction(
self.index_db.begin_with_config(None, None).await?,
target_db,
)),
TargetDb::Tickets => Ok(OpenTransaction(
self.tickets_db.begin_with_config(None, None).await?,
target_db,
)),
TargetDb::Peers => Ok(OpenTransaction(
self.peers_db.begin_with_config(None, None).await?,
target_db,
)),
TargetDb::Logs => Ok(OpenTransaction(
self.logs_db.begin_with_config(None, None).await?,
target_db,
)),
}
}
}
pub trait HoprDbAllOperations:
HoprDbGeneralModelOperations
+ HoprDbAccountOperations
+ HoprDbChannelOperations
+ HoprDbInfoOperations
+ HoprDbRegistryOperations
+ HoprDbTicketOperations
+ HoprDbPeersOperations
+ HoprDbResolverOperations
+ HoprDbProtocolOperations
+ HoprDbLogOperations
{
}
#[doc(hidden)]
pub mod prelude {
pub use super::*;
pub use crate::accounts::*;
pub use crate::channels::*;
pub use crate::db::*;
pub use crate::errors::*;
pub use crate::info::*;
pub use crate::registry::*;
pub use hopr_db_api::logs::*;
pub use hopr_db_api::peers::*;
pub use hopr_db_api::protocol::*;
pub use hopr_db_api::resolver::*;
pub use hopr_db_api::tickets::*;
}