rust - 如何实现 sqlx::FromRow 特征?
问题描述
我正在尝试手动实现sqlx::FrowRow
而不是使用derive
,因为需要一些自定义初始化逻辑(例如将整数转换i16
为枚举)。
默认 impl 生成如下:
use sqlx::FromRow;
impl FromRow for User {
fn from_row(row: &'r R) -> Result<Self, sqlx::Error> {
todo!()
}
}
但目前尚不清楚,我应该使用什么生命周期和类型。
解决方案
该FromRow
特征非常通用,因为它用于可能支持不同类型的不同后端数据库。您可以通过查看#[derive(FromRow)]
生成的内容(通过cargo expand
)来了解实现一个简单结构需要多少通用约束:
use sqlx::FromRow;
#[derive(FromRow)]
struct User {
name: String,
status: i16,
}
// generates
impl<'a, R: ::sqlx::Row> ::sqlx::FromRow<'a, R> for User
where
&'a ::std::primitive::str: ::sqlx::ColumnIndex<R>,
String: ::sqlx::decode::Decode<'a, R::Database>,
String: ::sqlx::types::Type<R::Database>,
i16: ::sqlx::decode::Decode<'a, R::Database>,
i16: ::sqlx::types::Type<R::Database>,
{
fn from_row(row: &'a R) -> ::sqlx::Result<Self> {
let name: String = row.try_get("name")?;
let status: i16 = row.try_get("status")?;
::std::result::Result::Ok(User { name, status })
}
}
它必须限制列可以按名称索引,并且限制列String
是i16
有效的并且可以从数据库中解码。
自己做,你最好选择你打算使用的数据库Row
类型AnyRow
( , MssqlRow
, MySqlRow
, PgRow
, SqliteRow
)并为此实现它。这里PgRow
用于 postgres:
use sqlx::{Row, FromRow, Error};
use sqlx::postgres::PgRow;
struct User {
name: String,
status: i16,
}
impl<'r> FromRow<'r, PgRow> for User {
fn from_row(row: &'r PgRow) -> Result<Self, Error> {
let name = row.try_get("name")?;
let status = row.try_get("status")?;
Ok(User{ name, status })
}
}
我确实想知道是否有不同的建议来进行自定义转换(通过 DTO 或其他机制)。
推荐阅读
- php - Laravel 雄辩,其中方法给出不区分大小写
- excel - 如何在电子表格中选择列中的用户输入值的行
- javascript - 为什么在评估函数时输入属性被调用数百次
- matlab - Matlab 多启动与 lsqnonlin
- excel - Outlook vba 调用 Excel dialog.show 失败
- elasticsearch - 设置本地弹性数据库
- spring-security - 我如何针对来自身份服务器的 SAML 断言授权用户(Wso2is 5.4.0)
- json - 如何处理 Kafka 主题中的 JSON?
- c++ - 比较 c++ 中的 uint8_t 和 uint16_t
- ios - 使用 ffmpeg,函数 av_find_input_format("avfoundation") 返回 null