Generics 柴油机的一般用途';s查找或筛选以执行删除
我正在尝试使用通用的Diesel函数来缩减重复性任务,比如根据主键删除一行 我得到的行的一般插入工作相对较快,但删除查询似乎相当困难。我尝试使用Generics 柴油机的一般用途';s查找或筛选以执行删除,generics,rust,generic-programming,rust-diesel,Generics,Rust,Generic Programming,Rust Diesel,我正在尝试使用通用的Diesel函数来缩减重复性任务,比如根据主键删除一行 我得到的行的一般插入工作相对较快,但删除查询似乎相当困难。我尝试使用find()和filter()来解决这个问题。我也咨询过类似的话题,但没有成功 使用find 使用柴油机::前奏::*; 使用diesel::query\u dsl::methods::FindDsl; 使用std::error::error; 发布结构数据库{ 连接:SQLITE连接, } impl数据库{ 发布fn删除行结果 哪里 T:FindDsl
find()
和filter()
来解决这个问题。我也咨询过类似的话题,但没有成功
使用find
使用柴油机::前奏::*;
使用diesel::query\u dsl::methods::FindDsl;
使用std::error::error;
发布结构数据库{
连接:SQLITE连接,
}
impl数据库{
发布fn删除行结果
哪里
T:FindDsl>::输出:柴油机::可识别,
>::作为柴油机输出::关联::HasTable>::作为柴油机输出的表::查询\u生成器::AsQuery>::查询`
=注意:由于`泛型的'diesel::query_builder::IntoUpdateTarget`的impl上的要求不容易,所以必需。在像diesel这样的高度泛型系统中,泛型更难实现
我更喜欢将步骤分解为非常小的部分,并尽可能避免链接。在这一过程中,您基本上需要为每个步骤添加特征边界。一个很好的方法是为非常复杂的特征边界使用/创建类型别名。并且您可以为您的特殊用途创建自己的类型别名
当我查看生成的错误消息时,我主要查看被调用的函数/方法所描述的类型边界
逐点:
来自
需要
调用delete
的结果类型是a,由T::Table
和T::WhereClause
参数化。这是自定义类型别名DeleteFindStatement
来自
使用柴油机::{
关联::HasTable,
助手类型::查找,
查询生成器:{DeleteStatement,IntoUpdateTarget},
查询\u dsl::方法::ExecuteSL,
};
类型DeleteFindStatement=
删除声明;
impl数据库{
pub fn remove_row(&self,table:Tbl,pk:pk)->结果
哪里
Tbl:FindDsl,
Find:IntoUpdateTarget,
DeleteFindStatement:ExecuteSL,
{
设find=table.find(pk);
让delete=diesel::delete(find);
删除。执行(&self.conn)?;
好(())
}
}
对于基于过滤器的版本,您需要自己尝试它,因为您没有提供足够的代码来说明id
应该是什么;如错误消息所示
另见:
即使主键在所有情况下都是&str
,使其成为通用键是否有好处
对我来说,使用泛型类型比插入一组泛型生存期参数更容易。好的,因此插入cargo errors中提到的特征边界在这里并没有真正的帮助。我基本上理解您在这里所做的事情,但遗憾的是,我没有看到从这些错误消息到您建议的解决方案的可理解的路径,even在执行小步骤时。因此,我想您只需要了解更多有关柴油机如何工作的信息。但是,非常感谢您的帮助!在过滤器
变体中,所有表都有一个主键“id:String”列。这需要如何指定?即使主键在所有情况下都是&str
,将主键设置为泛型是否有好处?
use diesel::prelude::*;
use diesel::query_dsl::methods::FilterDsl;
use std::error::Error;
pub struct DB {
conn: SqliteConnection,
}
impl DB {
pub fn remove_row<T>(&self, table: T, pk: &str) -> Result<(), Box<Error>>
where
T: FilterDsl<bool>,
<T as FilterDsl<bool>>::Output: diesel::Identifiable,
<T as FilterDsl<bool>>::Output: diesel::associations::HasTable,
{
diesel::delete(table.filter(id.eq(pk))).execute(&self.conn)?;
Ok(())
}
}
use diesel::{
associations::HasTable,
helper_types::Find,
query_builder::{DeleteStatement, IntoUpdateTarget},
query_dsl::methods::ExecuteDsl,
};
type DeleteFindStatement<F> =
DeleteStatement<<F as HasTable>::Table, <F as IntoUpdateTarget>::WhereClause>;
impl DB {
pub fn remove_row<Tbl, Pk>(&self, table: Tbl, pk: Pk) -> Result<(), Box<Error>>
where
Tbl: FindDsl<Pk>,
Find<Tbl, Pk>: IntoUpdateTarget,
DeleteFindStatement<Find<Tbl, Pk>>: ExecuteDsl<SqliteConnection>,
{
let find = table.find(pk);
let delete = diesel::delete(find);
delete.execute(&self.conn)?;
Ok(())
}
}