我想写一个带有签名的函数:
fn delete_direct(pool: &Pool, q: T);
该函数可用于任意表:
use crate::schema::users::dsl::*;
delete_direct(&pool, users.filter(name.eq("Harry")))
替换用法:
use crate::schema::users::dsl::*;
let mut conn = &pool.get().expect("Failed to get database connection");
diesel::delete(users.filter(name.eq("Harry")))
.execute(&mut conn)
.expect("Failed to run the delete query you specified");
这里的 pool
是 diesel::r2d2::Pool<ConnectionManager<PgConnection>>
类型,为简洁起见,它的别名为 Pool
类型。
我最终得到了这个功能:
fn delete_direct<T>(pool: &Pool, q: T) where
T: diesel::query_builder::IntoUpdateTarget,
<T as diesel::associations::HasTable>::Table: diesel::query_builder::QueryId + 'static,
<T as diesel::query_builder::IntoUpdateTarget>::WhereClause: diesel::query_builder::QueryId + diesel::query_builder::QueryFragment<diesel::pg::Pg>,
<<T as diesel::associations::HasTable>::Table as QuerySource>::FromClause: diesel::query_builder::QueryFragment<diesel::pg::Pg>,
{
let mut conn = pool.get().expect("Failed to get database connection");
diesel::delete(q)
.execute(&mut conn)
.expect("Failed to run the delete query you specified");
}
在编译器的帮助下满足diesel期望存在的所有特征约束。
这看起来很复杂,而且看起来我错过了一些明显的东西。 我是否遗漏了一些明显的东西,或者这是实现此功能的最简单方法?
delete
和 execute
的约束,您可以将其简化为:
use diesel::pg::Pg;
use diesel::query_builder::{DeleteStatement, IntoUpdateTarget, QueryFragment, QueryId};
use diesel::RunQueryDsl;
fn delete_direct<T>(pool: &Pool, q: T)
where
T: IntoUpdateTarget,
DeleteStatement<T::Table, T::WhereClause>: QueryFragment<Pg> + QueryId,
{
let mut conn = pool.get().expect("Failed to get database connection");
diesel::delete(q)
.execute(&mut conn)
.expect("Failed to run the delete query you specified");
}
但总的来说,提取柴油碎片很容易需要大量令人眼花缭乱的约束才能正确处理。我个人觉得不值得这么麻烦。