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
18use async_trait::async_trait;
19use futures::future::BoxFuture;
20pub use hopr_db_api as api;
21use hopr_db_api::{
22 logs::HoprDbLogOperations, peers::HoprDbPeersOperations, protocol::HoprDbProtocolOperations,
23 resolver::HoprDbResolverOperations, tickets::HoprDbTicketOperations,
24};
25use sea_orm::TransactionTrait;
26pub use sea_orm::{DatabaseConnection, DatabaseTransaction};
27
28use crate::{
29 accounts::HoprDbAccountOperations,
30 channels::HoprDbChannelOperations,
31 db::HoprDb,
32 errors::{DbSqlError, Result},
33 info::HoprDbInfoOperations,
34 registry::HoprDbRegistryOperations,
35};
36
37pub const SINGULAR_TABLE_FIXED_ID: i32 = 1;
39
40pub type DbTimestamp = chrono::DateTime<chrono::Utc>;
42
43#[derive(Debug)]
48pub struct OpenTransaction(DatabaseTransaction, TargetDb);
49
50impl OpenTransaction {
51 pub async fn perform<F, T, E>(self, callback: F) -> std::result::Result<T, E>
54 where
55 F: for<'c> FnOnce(&'c OpenTransaction) -> BoxFuture<'c, std::result::Result<T, E>> + Send,
56 T: Send,
57 E: std::error::Error + From<DbSqlError>,
58 {
59 let res = callback(&self).await;
60
61 if res.is_ok() {
62 self.commit().await?;
63 } else {
64 self.rollback().await?;
65 }
66 res
67 }
68
69 pub async fn commit(self) -> Result<()> {
71 Ok(self.0.commit().await?)
72 }
73
74 pub async fn rollback(self) -> Result<()> {
76 Ok(self.0.rollback().await?)
77 }
78}
79
80impl AsRef<DatabaseTransaction> for OpenTransaction {
81 fn as_ref(&self) -> &DatabaseTransaction {
82 &self.0
83 }
84}
85
86impl From<OpenTransaction> for DatabaseTransaction {
87 fn from(value: OpenTransaction) -> Self {
88 value.0
89 }
90}
91
92pub type OptTx<'a> = Option<&'a OpenTransaction>;
95
96#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
100pub enum TargetDb {
101 #[default]
102 Index,
104 Tickets,
106 Peers,
108 Logs,
110}
111
112#[async_trait]
113pub trait HoprDbGeneralModelOperations {
114 fn conn(&self, target_db: TargetDb) -> &DatabaseConnection;
119
120 async fn begin_transaction_in_db(&self, target: TargetDb) -> Result<OpenTransaction>;
122
123 async fn begin_transaction(&self) -> Result<OpenTransaction> {
125 self.begin_transaction_in_db(Default::default()).await
126 }
127
128 async fn nest_transaction_in_db(&self, tx: OptTx<'_>, target_db: TargetDb) -> Result<OpenTransaction> {
138 if let Some(t) = tx {
139 assert_eq!(t.1, target_db, "attempt to create nest into tx from a different db");
140 Ok(OpenTransaction(t.as_ref().begin().await?, target_db))
141 } else {
142 self.begin_transaction_in_db(target_db).await
143 }
144 }
145
146 async fn nest_transaction(&self, tx: OptTx<'_>) -> Result<OpenTransaction> {
148 self.nest_transaction_in_db(tx, Default::default()).await
149 }
150}
151
152#[async_trait]
153impl HoprDbGeneralModelOperations for HoprDb {
154 fn conn(&self, target_db: TargetDb) -> &DatabaseConnection {
156 match target_db {
157 TargetDb::Index => &self.index_db,
158 TargetDb::Tickets => &self.tickets_db,
159 TargetDb::Peers => &self.peers_db,
160 TargetDb::Logs => &self.logs_db,
161 }
162 }
163
164 async fn begin_transaction_in_db(&self, target_db: TargetDb) -> Result<OpenTransaction> {
166 match target_db {
167 TargetDb::Index => Ok(OpenTransaction(
168 self.index_db.begin_with_config(None, None).await?,
169 target_db,
170 )),
171 TargetDb::Tickets => Ok(OpenTransaction(
173 self.tickets_db.begin_with_config(None, None).await?,
174 target_db,
175 )),
176 TargetDb::Peers => Ok(OpenTransaction(
177 self.peers_db.begin_with_config(None, None).await?,
178 target_db,
179 )),
180 TargetDb::Logs => Ok(OpenTransaction(
181 self.logs_db.begin_with_config(None, None).await?,
182 target_db,
183 )),
184 }
185 }
186}
187
188pub trait HoprDbAllOperations:
190 HoprDbGeneralModelOperations
191 + HoprDbAccountOperations
192 + HoprDbChannelOperations
193 + HoprDbInfoOperations
194 + HoprDbLogOperations
195 + HoprDbPeersOperations
196 + HoprDbProtocolOperations
197 + HoprDbRegistryOperations
198 + HoprDbResolverOperations
199 + HoprDbTicketOperations
200{
201}
202
203#[doc(hidden)]
204pub mod prelude {
205 pub use hopr_db_api::{logs::*, peers::*, protocol::*, resolver::*, tickets::*};
206
207 pub use super::*;
208 pub use crate::{accounts::*, channels::*, db::*, errors::*, info::*, registry::*};
209}