digital-society-coop / axum-sqlx-tx

Request-scoped sqlx transactions for axum
MIT License
45 stars 11 forks source link

How to pass a Tx into other functions #20

Closed arlyon closed 1 year ago

arlyon commented 1 year ago

I have a function such as this:

async fn a_b(executor: &mut Tx<Sqlite>) {
    let a = sqlx::query_as!(A, "select * from a")
        .fetch_all(executor)
        .await
        .unwrap();

    let b = sqlx::query_as!(B, "select * from b")
        .fetch_all(executor)
        .await
        .unwrap();

  (a, b)
}

And I get the following error:

error[E0382]: use of moved value: `executor`
   --> src/main.rs:353:20
    |
337 | async fn a_b(executor: &mut Tx<Sqlite>) {
    |                          -------- move occurs because `executor` has type `&mut Tx<Sqlite>`, which does not implement the `Copy` trait
338 |     let a = sqlx::query_as!(A, "select *...
339 |         .fetch_all(executor)
    |                    -------- value moved here
...
353 |         .fetch_one(executor)
    |                    ^^^^^^^^ value used here after move

What is the recommended usage here? I take it we are not supposed to use Tx, but in that case what should be used instead? Moving the type into the object is not desirable as I need it later on.

A seemingly-equivalent statement compiles fine, so I assuming there is some generics trickery that needs doing.

async fn test(val: &mut String) {
    test2(val).await;
    test2(val).await;
}

async fn test2(val: &mut String) {}

Edit: adding as_mut to the first call seems to have done the trick, though I wish I knew why the two samples are different.. feel free to close.