-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic usage of an executor or alike (Pool, Connection, Transaction) that allows to use the top level transaction when requesting a transaction #351
Comments
It looks like you could use the |
Transactions can now be started from This combined with the existing ability of transactions to derefence into connections should allow for this. |
Does this solution have other downsides though? The docs suggest that using Pool over a sticky connection, of course a single connection would be required for transactional operations, but for simple data fetching, it would work with a pool as well? |
I'm still having issues passing around the This errors occurs when trying to use an inner transaction.
I've also had an error without the inner transaction, changing the create_user fn to this async fn create_user<C>(name: &str, conn: &mut C) -> Result<(), sqlx::Error>
where C: Connection<Database = Postgres> {
log("Creating user...", conn).await?;
sqlx::query("SELECT 1")
.execute(conn)
.await?;
log("User created.", conn).await?;
Ok(())
} produces a move on execute
|
I can't find this in the docs or code, but it should solve the compilation problem. |
This error is due to async fn create_user<C>(name: &str, conn: &mut C) -> Result<(), sqlx::Error>
where
C: Connection<Database = Postgres>,
{
log("Creating user...", conn).await?;
conn.execute(sqlx::query("SELECT 1")).await?;
log("User created.", conn).await?;
Ok(())
} |
Sorry I meant the change has been done on master. It's not yet released. |
Hope it gets versioned soon then! I'll try the other api as well later @Mcat12 Thanks for the suggestion |
Reading up in the thread,
This is because of the generic context. Rust doesn't understand that it can just reborrow the sqlx::query("SELECT 1")
.execute(&mut *conn)
.await?; |
Trying to use the manual reborrow still does not work for me, see the code snippet below: pub async fn create_or_update_address<C>(
params: &CreateOrUpdateAddressParams,
conn: &mut C,
) -> Result<CreateOrUpdateAddressResult, ServiceError<CreateOrUpdateAddressError>>
where
C: Connection<Database = Postgres>,
{
params.validate().map_err(|err| err.into_service_error())?;
let result = sqlx::query_as!(
TblAddress,
"
SELECT *
FROM tbl_address
WHERE country_id = $1 and
state_or_province_name = $2 and
city_name = $3 and
street_name = $4 and
house_number = $5 and
annex = $6 and
zip_code = $7
",
params.country_id,
params.state_or_province_name,
params.city_name,
params.street_name,
params.house_number,
params.annex,
params.zip_code
)
.fetch_optional(&mut *conn)
.await
.map_err(|err| err.into_service_error())?;
todo!()
} produces error error[E0277]: the trait bound `C: std::marker::Copy` is not satisfied
--> src/services/mod.rs:40:21
|
40 | .fetch_optional(&mut *conn)
| ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `C`
|
help: consider further restricting this bound with `+ std::marker::Copy`
--> src/services/mod.rs:15:5
|
15 | C: Connection<Database = Postgres>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required because of the requirements on the impl of `sqlx_core::executor::RefExecutor<'_>` for `&mut C`
error[E0277]: the trait bound `C: sqlx_core::executor::RefExecutor<'_>` is not satisfied
--> src/services/mod.rs:40:21
|
40 | .fetch_optional(&mut *conn)
| ^^^^^^^^^^ the trait `sqlx_core::executor::RefExecutor<'_>` is not implemented for `C`
|
help: consider further restricting this bound with `+ sqlx_core::executor::RefExecutor<'_>`
--> src/services/mod.rs:15:5
|
15 | C: Connection<Database = Postgres>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required because of the requirements on the impl of `sqlx_core::executor::RefExecutor<'_>` for `&mut C` As for @Mcat12 's suggested approach, which does work, but the |
This is all fixed on master so I'm going to close this. See #361 for tracking on the release. |
I am trying to create functions that have some functionality, that needs to fetch or mutate the database based on some logic. Sometimes this requires a transaction, sometimes it just needs a connection to fetch some data with. This works great by just passing in connection pool.
But what do I do when I want to nest these functions? Here's a simple (maybe non practical) POC.
So what I'd want to happen is:
I've looked into using a generic as such
which does work for abstracting the pool and connection, but doesn't give the ability to begin a new transaction or continue with a current ongoing one.
Any ideas?
The text was updated successfully, but these errors were encountered: