How do you generalize connections from a Pool and a Transaction while being able to enter new transactions? #3618
Unanswered
insomnimus
asked this question in
Q&A
Replies: 1 comment
-
This is definitely possible. As you indicate, you can create a trait (e.g. use sqlx::{Connection, PgExecutor, Postgres, Transaction};
trait Sql {
fn executor(&mut self) -> impl PgExecutor;
async fn begin(&mut self) -> Result<Transaction<'_, Postgres>, sqlx::Error>;
}
impl Sql for sqlx::PgPool {
fn executor(&mut self) -> impl PgExecutor {
&*self
}
async fn begin(&mut self) -> Result<Transaction<'_, Postgres>, sqlx::Error> {
sqlx::PgPool::begin(self).await
}
}
impl<'c> Sql for Transaction<'c, Postgres> {
fn executor(&mut self) -> impl PgExecutor {
&mut **self
}
async fn begin(&mut self) -> Result<Transaction<'_, Postgres>, sqlx::Error> {
Connection::begin(&mut **self).await
}
}
async fn work(mut pool: sqlx::PgPool) {
test_tx(&mut pool).await
}
async fn test<S: Sql>(sql: &mut S) {
sqlx::query("select * from test").execute(sql.executor()).await.unwrap();
}
async fn test_tx<S: Sql>(sql: &mut S) {
let mut tx = sql.begin().await.unwrap();
sqlx::query("select * from test2").execute(tx.executor()).await.unwrap();
test(&mut tx).await;
tx.commit().await.unwrap();
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I'm trying to abstract away common database operations in a modular fashion, meaning generic functions.
I need a "database" value that
But I also need that "database" type to include
&Pool
and&mut SqliteConnection
(or&mut Transaction
, but I can deref manually), via a trait.1 and 3 seem to be doable. I'm most having trouble with 2 because there's no trait to generalize it with, and my attempts of making one myself weren't successful.
Given those requirements, I'm unable to find a solution.
I was envisioning something similar to below (making up a trait that would encompass all that, called
Sql
; it's just to demonstrate the point):This example's a bit contrived, and I left out the bit about being able to call it with a
Pool
as well as a&mut impl Connection
/Transaction
for brevity. I'm hoping it's not hard to imagine use cases where that would be desired.So... How do we actually do this kind of thing with sqlx?
Beta Was this translation helpful? Give feedback.
All reactions