1pub mod accounts;
5mod cache;
6pub mod channels;
7pub mod db;
8pub mod errors;
9pub mod info;
10pub mod logs;
11pub mod peers;
12pub mod protocol;
13pub mod registry;
14pub mod resolver;
15mod ticket_manager;
16pub mod tickets;
17
18pub use hopr_db_api as api;
19
20pub use sea_orm::DatabaseConnection;
21pub use sea_orm::DatabaseTransaction;
22
23use crate::accounts::HoprDbAccountOperations;
24use crate::channels::HoprDbChannelOperations;
25use async_trait::async_trait;
26use futures::future::BoxFuture;
27use sea_orm::TransactionTrait;
28
29use crate::db::HoprDb;
30use crate::errors::{DbSqlError, Result};
31use crate::info::HoprDbInfoOperations;
32use crate::registry::HoprDbRegistryOperations;
33use hopr_db_api::logs::HoprDbLogOperations;
34use hopr_db_api::peers::HoprDbPeersOperations;
35use hopr_db_api::protocol::HoprDbProtocolOperations;
36use hopr_db_api::resolver::HoprDbResolverOperations;
37use hopr_db_api::tickets::HoprDbTicketOperations;
38
39pub const SINGULAR_TABLE_FIXED_ID: i32 = 1;
41
42pub type DbTimestamp = chrono::DateTime<chrono::Utc>;
44
45#[derive(Debug)]
50pub struct OpenTransaction(DatabaseTransaction, TargetDb);
51
52impl OpenTransaction {
53 pub async fn perform<F, T, E>(self, callback: F) -> std::result::Result<T, E>
56 where
57 F: for<'c> FnOnce(&'c OpenTransaction) -> BoxFuture<'c, std::result::Result<T, E>> + Send,
58 T: Send,
59 E: std::error::Error + From<DbSqlError>,
60 {
61 let res = callback(&self).await;
62
63 if res.is_ok() {
64 self.commit().await?;
65 } else {
66 self.rollback().await?;
67 }
68 res
69 }
70
71 pub async fn commit(self) -> Result<()> {
73 Ok(self.0.commit().await?)
74 }
75
76 pub async fn rollback(self) -> Result<()> {
78 Ok(self.0.rollback().await?)
79 }
80}
81
82impl AsRef<DatabaseTransaction> for OpenTransaction {
83 fn as_ref(&self) -> &DatabaseTransaction {
84 &self.0
85 }
86}
87
88impl From<OpenTransaction> for DatabaseTransaction {
89 fn from(value: OpenTransaction) -> Self {
90 value.0
91 }
92}
93
94pub type OptTx<'a> = Option<&'a OpenTransaction>;
97
98#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
102pub enum TargetDb {
103 #[default]
104 Index,
106 Tickets,
108 Peers,
110 Logs,
112}
113
114#[async_trait]
115pub trait HoprDbGeneralModelOperations {
116 fn conn(&self, target_db: TargetDb) -> &DatabaseConnection;
121
122 async fn begin_transaction_in_db(&self, target: TargetDb) -> Result<OpenTransaction>;
124
125 async fn begin_transaction(&self) -> Result<OpenTransaction> {
127 self.begin_transaction_in_db(Default::default()).await
128 }
129
130 async fn nest_transaction_in_db(&self, tx: OptTx<'_>, target_db: TargetDb) -> Result<OpenTransaction> {
140 if let Some(t) = tx {
141 assert_eq!(t.1, target_db, "attempt to create nest into tx from a different db");
142 Ok(OpenTransaction(t.as_ref().begin().await?, target_db))
143 } else {
144 self.begin_transaction_in_db(target_db).await
145 }
146 }
147
148 async fn nest_transaction(&self, tx: OptTx<'_>) -> Result<OpenTransaction> {
150 self.nest_transaction_in_db(tx, Default::default()).await
151 }
152}
153
154#[async_trait]
155impl HoprDbGeneralModelOperations for HoprDb {
156 fn conn(&self, target_db: TargetDb) -> &DatabaseConnection {
158 match target_db {
159 TargetDb::Index => &self.index_db,
160 TargetDb::Tickets => &self.tickets_db,
161 TargetDb::Peers => &self.peers_db,
162 TargetDb::Logs => &self.logs_db,
163 }
164 }
165
166 async fn begin_transaction_in_db(&self, target_db: TargetDb) -> Result<OpenTransaction> {
168 match target_db {
169 TargetDb::Index => Ok(OpenTransaction(
170 self.index_db.begin_with_config(None, None).await?,
171 target_db,
172 )),
173 TargetDb::Tickets => Ok(OpenTransaction(
175 self.tickets_db.begin_with_config(None, None).await?,
176 target_db,
177 )),
178 TargetDb::Peers => Ok(OpenTransaction(
179 self.peers_db.begin_with_config(None, None).await?,
180 target_db,
181 )),
182 TargetDb::Logs => Ok(OpenTransaction(
183 self.logs_db.begin_with_config(None, None).await?,
184 target_db,
185 )),
186 }
187 }
188}
189
190pub trait HoprDbAllOperations:
192 HoprDbGeneralModelOperations
193 + HoprDbAccountOperations
194 + HoprDbChannelOperations
195 + HoprDbInfoOperations
196 + HoprDbRegistryOperations
197 + HoprDbTicketOperations
198 + HoprDbPeersOperations
199 + HoprDbResolverOperations
200 + HoprDbProtocolOperations
201 + HoprDbLogOperations
202{
203}
204
205#[doc(hidden)]
206pub mod prelude {
207 pub use super::*;
208 pub use crate::accounts::*;
209 pub use crate::channels::*;
210 pub use crate::db::*;
211 pub use crate::errors::*;
212 pub use crate::info::*;
213 pub use crate::registry::*;
214 pub use hopr_db_api::logs::*;
215 pub use hopr_db_api::peers::*;
216 pub use hopr_db_api::protocol::*;
217 pub use hopr_db_api::resolver::*;
218 pub use hopr_db_api::tickets::*;
219}