From slqx 0.7 this clean code doesn't work anymore and I cannot understand why

A few months ago - coming from Golang - I was looking for a way to use both direct queries and queries in transactions (I'm also using a clean code architecture, so I cannot call sqlx methods directly).

A very nice person on the rust Discord channel helped me put this code together and it works great: GitHub - frederikhors/iss-sqlx-0.7.

This allows me to use code like this:

let mut tx = repo.start_transaction().await?;

let available_seats = tx.search_for_available_seats(stadium_id).await?;

let confirmed_seat = tx.confirm_seat(available_seats[0]).await?;

tx.commit().await?;

in addition to this:

let example = repo.clone_boxed().search_for_available_seats(stadium_id).await?;

Everything works perfectly with sqlx 0.6.3, but now with sqlx 0.7 I'm having this error:

error[E0277]: the trait bound `&'this mut Transaction<'static, Postgres>: sqlx::Executor<'this>` is not satisfied
  --> src\main.rs:99:28
   |
99 |     type Executor<'this> = &'this mut Self;
   |                            ^^^^^^^^^^^^^^^ the trait `sqlx::Executor<'this>` is not implemented for `&'this mut Transaction<'static, Postgres>`
   |
   = help: the following other types implement trait `sqlx::Executor<'c>`:
             <&'c mut PgConnection as sqlx::Executor<'c>>
             <&'c mut PgListener as sqlx::Executor<'c>>
             <&Pool<DB> as sqlx::Executor<'p>>
   = note: required for `<Transaction<'static, Postgres> as Executor>::Executor<'this>` to implement `PgExecutor<'this>`
note: required by a bound in `Executor::Executor`
  --> src\main.rs:78:41
   |
78 |     type Executor<'this>: Send + Sync + sqlx::PgExecutor<'this>;
   |                                         ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Executor::Executor`

For more information about this error, try `rustc --explain E0277`.

I saw the note in CHANGELOG about Executor trait but I don't know how to fix it in this case:

image

Could you suggest me a way to fix it?

Can you think of an alternative way to use instead of this Executor trait?

The custom trait

pub trait Executor: Send + Sync {
    type Executor<'this>: Send + Sync + sqlx::PgExecutor<'this>;

    // From https://users.rust-lang.org/t/why-does-this-impl-executor-does-not-live-long-enough/94241
    fn _disable_lint(e: Self::Executor<'_>) -> Self::Executor<'_>;

    fn as_executor(&mut self) -> Self::Executor<'_>;
}

impl Executor for sqlx::PgPool {
    type Executor<'this> = &'this Self;

    fn _disable_lint(e: Self::Executor<'_>) -> Self::Executor<'_> {
        e
    }

    fn as_executor(&mut self) -> Self::Executor<'_> {
        self
    }
}

impl Executor for sqlx::Transaction<'static, sqlx::Postgres> {
    type Executor<'this> = &'this mut Self;

    fn _disable_lint(e: Self::Executor<'_>) -> Self::Executor<'_> {
        e
    }

    fn as_executor(&mut self) -> Self::Executor<'_> {
        self
    }
}

As the changelog notes, &mut Transaction no longer implements Executor. Instead you need to use the Connection that Transaction derefs to as the associated type.

impl Executor for sqlx::Transaction<'static, sqlx::Postgres> {
    type Executor<'this> = &'this mut <sqlx::Postgres as sqlx::Database>::Connection;

which is the same as:

type Executor<'this> = &'this mut sqlx::PgConnection;

right?

Correct

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.