接受 SQLx PgPool 或 MySqlPool 的通用函数

pat*_*oid 11 rust rust-sqlx

我想设置一个接受 SQLx PgPoolMySqlPool的通用函数。

use dotenv::dotenv;
use sqlx::postgres::PgPool;
use sqlx::{Pool, Database};
use std::env;

#[derive(Debug)]
struct Todo {
    id: i64,
    description: String,
    done: bool,
}

#[actix_web::main]
async fn main() -> anyhow::Result<()> {
    dotenv().ok();
    let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
    list_todos(&pool).await?;
    Ok(())
}



async fn list_todos<D: Database>(pool: &Pool<D>) -> anyhow::Result<Vec<Todo>> {
    let todos = sqlx::query_as!(
        Todo,
        r#"
        SELECT id, description, done
        FROM todos
        ORDER BY id
        "#
    )
    .fetch_all(pool)
    .await?;

    Ok(todos)
}
Run Code Online (Sandbox Code Playgroud)

我看到的错误是:

32 |     .fetch_all(pool)
   |      ^^^^^^^^^ expected type parameter `D`, found struct `Postgres`
   |
   = note: expected type parameter `D`
                      found struct `Postgres`

error[E0277]: the trait bound `for<'c> &'c mut <D as sqlx::Database>::Connection: Executor<'c>` is not satisfied
Run Code Online (Sandbox Code Playgroud)

有关如何设置函数以接受 PgPool 或 MySqlPool 参数的任何提示吗?谢谢

Net*_*ave 0

无法正确测试它,但您可以Executor直接用作泛型。从文档中:

包含或可以提供数据库连接以用于对数据库执行查询的类型。

不保证连续查询在同一物理数据库连接上运行。

连接是一个执行器,它保证连续的查询在同一个物理数据库连接上运行。

实施目的如下:

&Pool &mut PoolConnection &mut 连接

async fn list_todos<'e, Exe: Executor<'e>>(executor: Exe) -> anyhow::Result<()>
where
    <Exe::Database as HasArguments<'e>>::Arguments:
        IntoArguments<'e, <Exe as Executor<'e>>::Database>,
{
    let todos = sqlx::query(
        r#"
        SELECT id, description, done
        FROM todos
        ORDER BY id
        "#,
    )
    .execute(executor)
    .await?;

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

免责声明:由于我没有正确测试它的环境,因此返回类型和其他内容发生了一些变化。但对于执行器绑定来说,它的编译没有问题。你必须适应剩下的事情。