我想设置一个接受 SQLx PgPool或MySqlPool的通用函数。
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 参数的任何提示吗?谢谢
无法正确测试它,但您可以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)
免责声明:由于我没有正确测试它的环境,因此返回类型和其他内容发生了一些变化。但对于执行器绑定来说,它的编译没有问题。你必须适应剩下的事情。