cdk_sql_common/mint/
mod.rs1use std::fmt::Debug;
12use std::sync::Arc;
13
14use async_trait::async_trait;
15use cdk_common::database::{self, DbTransactionFinalizer, Error, MintDatabase};
16
17use crate::common::migrate;
18use crate::database::{ConnectionWithTransaction, DatabaseExecutor};
19use crate::pool::{DatabasePool, Pool, PooledResource};
20
21mod auth;
22mod completed_operations;
23mod keys;
24mod keyvalue;
25mod proofs;
26mod quotes;
27mod saga;
28mod signatures;
29
30#[rustfmt::skip]
31mod migrations {
32 include!(concat!(env!("OUT_DIR"), "/migrations_mint.rs"));
33}
34
35pub use auth::SQLMintAuthDatabase;
36#[cfg(feature = "prometheus")]
37use cdk_prometheus::METRICS;
38use migrations::MIGRATIONS;
39
40#[derive(Debug, Clone)]
42pub struct SQLMintDatabase<RM>
43where
44 RM: DatabasePool + 'static,
45{
46 pub(crate) pool: Arc<Pool<RM>>,
47}
48
49#[allow(missing_debug_implementations)]
51pub struct SQLTransaction<RM>
52where
53 RM: DatabasePool + 'static,
54{
55 pub(crate) inner: ConnectionWithTransaction<RM::Connection, PooledResource<RM>>,
56}
57
58impl<RM> SQLMintDatabase<RM>
59where
60 RM: DatabasePool + 'static,
61{
62 pub async fn new<X>(db: X) -> Result<Self, Error>
64 where
65 X: Into<RM::Config>,
66 {
67 let pool = Pool::new(db.into());
68
69 Self::migrate(pool.get().map_err(|e| Error::Database(Box::new(e)))?).await?;
70
71 Ok(Self { pool })
72 }
73
74 async fn migrate(conn: PooledResource<RM>) -> Result<(), Error> {
76 let tx = ConnectionWithTransaction::new(conn).await?;
77 migrate(&tx, RM::Connection::name(), MIGRATIONS).await?;
78 tx.commit().await?;
79 Ok(())
80 }
81}
82
83#[async_trait]
84impl<RM> database::MintTransaction<Error> for SQLTransaction<RM> where RM: DatabasePool + 'static {}
85
86#[async_trait]
87impl<RM> DbTransactionFinalizer for SQLTransaction<RM>
88where
89 RM: DatabasePool + 'static,
90{
91 type Err = Error;
92
93 async fn commit(self: Box<Self>) -> Result<(), Error> {
94 let result = self.inner.commit().await;
95 #[cfg(feature = "prometheus")]
96 {
97 let success = result.is_ok();
98 METRICS.record_mint_operation("transaction_commit", success);
99 METRICS.record_mint_operation_histogram("transaction_commit", success, 1.0);
100 }
101
102 Ok(result?)
103 }
104
105 async fn rollback(self: Box<Self>) -> Result<(), Error> {
106 let result = self.inner.rollback().await;
107
108 #[cfg(feature = "prometheus")]
109 {
110 let success = result.is_ok();
111 METRICS.record_mint_operation("transaction_rollback", success);
112 METRICS.record_mint_operation_histogram("transaction_rollback", success, 1.0);
113 }
114 Ok(result?)
115 }
116}
117
118#[async_trait]
119impl<RM> MintDatabase<Error> for SQLMintDatabase<RM>
120where
121 RM: DatabasePool + 'static,
122{
123 async fn begin_transaction(
124 &self,
125 ) -> Result<Box<dyn database::MintTransaction<Error> + Send + Sync>, Error> {
126 let tx = SQLTransaction {
127 inner: ConnectionWithTransaction::new(
128 self.pool.get().map_err(|e| Error::Database(Box::new(e)))?,
129 )
130 .await?,
131 };
132
133 Ok(Box::new(tx))
134 }
135}