I want to write a function with the signature:
fn delete_direct(pool: &Pool, q: T);
That function can be used for an arbitrary table:
use crate::schema::users::dsl::*;
delete_direct(&pool, users.filter(name.eq("Harry")))
To replace the usage:
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
here is of type diesel::r2d2::Pool<ConnectionManager<PgConnection>>
, which is aliased to type Pool
for brevity.
I ended up with this function:
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");
}
With the help of the compiler to satisfy all trait constraints that diesel expects to be present.
This looks complex, and looks like I'm missing something obvious. Am I missing something obvious or is this the simplest way to implement this function?
By mimicking the constraints on delete
and execute
, you can simplify it to:
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");
}
In general though, abstracting over diesel fragments can very easily require a dizzying number of constraints to handle properly. I personally don't find it worth the trouble.