Skip to content

Commit c6a3066

Browse files
committed
feat: support with_transaction in postgres client
1 parent eb1750d commit c6a3066

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

core/src/database/postgres/client.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{env, time::Duration};
2+
use std::future::Future;
23

34
use bb8::{Pool, RunError};
45
use bb8_postgres::PostgresConnectionManager;
@@ -11,16 +12,16 @@ use tokio::{task, time::timeout};
1112
use tokio_postgres::{
1213
binary_copy::BinaryCopyInWriter,
1314
config::SslMode,
14-
types::{ToSql, Type as PgType},
1515
Config, CopyInSink, Error as PgError, Row, Statement, ToStatement,
1616
Transaction as PgTransaction,
1717
};
18+
pub use tokio_postgres::types::{ToSql, Type as PgType};
1819
use tracing::{debug, error};
19-
2020
use crate::database::postgres::{
2121
generate::generate_event_table_columns_names_sql, sql_type_wrapper::EthereumSqlTypeWrapper,
2222
};
2323

24+
2425
pub fn connection_string() -> Result<String, env::VarError> {
2526
dotenv().ok();
2627
let connection = env::var("DATABASE_URL")?;
@@ -57,8 +58,25 @@ pub enum PostgresError {
5758
ConnectionPoolError(#[from] RunError<tokio_postgres::Error>),
5859
}
5960

60-
pub struct PostgresTransaction {
61-
pub transaction: PgTransaction<'static>,
61+
pub struct PostgresTransaction<'a> {
62+
pub transaction: PgTransaction<'a>,
63+
}
64+
impl<'a> PostgresTransaction<'a> {
65+
pub async fn execute(
66+
&mut self,
67+
query: &str,
68+
params: &[&(dyn ToSql + Sync)],
69+
) -> Result<u64, PostgresError> {
70+
self.transaction.execute(query, params).await.map_err(PostgresError::PgError)
71+
}
72+
73+
pub async fn commit(self) -> Result<(), PostgresError> {
74+
self.transaction.commit().await.map_err(PostgresError::PgError)
75+
}
76+
77+
pub async fn rollback(self) -> Result<(), PostgresError> {
78+
self.transaction.rollback().await.map_err(PostgresError::PgError)
79+
}
6280
}
6381

6482
#[derive(thiserror::Error, Debug)]
@@ -167,14 +185,27 @@ impl PostgresClient {
167185
conn.prepare_typed(query, parameter_types).await.map_err(PostgresError::PgError)
168186
}
169187

170-
pub async fn transaction(&self) -> Result<PostgresTransaction, PostgresError> {
171-
let mut conn = self.pool.get().await?;
188+
pub async fn with_transaction<F, Fut, T, Q>(
189+
&self,
190+
query: &Q,
191+
params: &[&(dyn ToSql + Sync)],
192+
f: F,
193+
) -> Result<T, PostgresError>
194+
where
195+
F: FnOnce(u64) -> Fut + Send,
196+
Fut: Future<Output = Result<T, PostgresError>> + Send,
197+
Q: ?Sized + ToStatement,
198+
{
199+
let mut conn = self.pool.get().await.map_err(PostgresError::ConnectionPoolError)?;
172200
let transaction = conn.transaction().await.map_err(PostgresError::PgError)?;
173201

174-
// Wrap the transaction in a static lifetime
175-
let boxed_transaction: Box<PgTransaction<'static>> =
176-
unsafe { std::mem::transmute(Box::new(transaction)) };
177-
Ok(PostgresTransaction { transaction: *boxed_transaction })
202+
let count = transaction.execute(query, params).await.map_err(PostgresError::PgError)?;
203+
204+
let result = f(count).await?;
205+
206+
transaction.commit().await.map_err(PostgresError::PgError)?;
207+
208+
Ok(result)
178209
}
179210

180211
pub async fn query<T>(
@@ -343,4 +374,4 @@ impl PostgresClient {
343374
.map_err(|e| e.to_string())
344375
}
345376
}
346-
}
377+
}

documentation/docs/pages/docs/changelog.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
### Features
77
-------------------------------------------------
88
- feat: expose an insert_bulk new postgres function to make inserting bulk data easier
9-
- feat: expose new ethereum sql type wrappers for bytes types
9+
- feat: expose new ethereum sql type wrappers for bytes types#
10+
- feat: expose postgres ToSql trait
11+
- feat: support with_transaction in postgres client
1012

1113
### Bug fixes
1214
-------------------------------------------------

0 commit comments

Comments
 (0)