Skip to content

[Ideas Wanted] Generically accepting a &Pool or &mut Connection and allowing the argument to be used more than once #419

Open
@mehcode

Description

@mehcode

Sometimes I find it easier to start with how this should look to the user:

// async fn foo(executor: impl Executor<'_, Database = Postgres>) -> anyhow::Result<()> { 
async fn foo(executor: impl PgExecutor<'_>) -> anyhow::Result<()> { 
  assert!(executor.fetch_one("SELECT 2").await?.get(0) == 2_i32);
  assert!(executor.fetch_one("SELECT 5").await?.get(0) == 5_i32);

  Ok(())
}

Anything goes, no matter ugly it makes the SQLx side look as long as it doesn't cause the compiler to ICE if you look at it funny (so try to avoid too many HRTBs).

I can think of a few different ways to do this given full access to the nightly compiler (GATs, arbitrary self types) but we do need this to work on stable.

The key issue is fetch_one is defined as fetch_one(self, query: impl Execute). Executor is then implemented for &Pool and &mut PgConnection, &mut MssqlConnection, etc.

Note that this example works if instead of the generic argument it is &mut PgConnection or &Pool. This works because of the implicit re-borrowing that happens outside of a generic context. I'm reasonably sure we can't mimic re-borrowing in the trait system due to lack of GATs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is neededneeds rust featureThis issue or PR needs a Rust feature to be stabilized before it can be merged into master

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions