6个版本
0.2.4 | 2024年5月1日 |
---|---|
0.2.3 | 2024年3月14日 |
0.2.2 | 2024年1月2日 |
0.2.1 | 2023年11月29日 |
0.1.0 | 2023年5月28日 |
#5 in #from-row
每月下载量 48次
用于 rusqlite-from-row
18KB
381 行
rusqlite-from-row
从FromRow
派生以生成结构体与rusqlite行之间的映射。
[dependencies]
rusqlite_from_row = "0.2.4"
用法
派生FromRow
并执行查询以选择具有相同名称和类型的列。
use rusqlite_from_row::FromRow;
#[derive(FromRow)]
struct Todo {
todo_id: i32,
text: String,
author_id: i32,
}
let row = connection.query_row("SELECT todo_id, text, author_id FROM todos", [], Todo::try_from_row).unwrap();
嵌套、连接和平铺
您可能希望将两个表之间的连接表示为嵌套结构体。这可以通过在嵌套字段上使用#[from_row(flatten)]
来实现。这将委托该字段的创建到具有相同行的FromRow::from_row
,而不是到FromSql
。
由于表在连接时可能存在命名冲突,您可以指定一个prefix = ""
来唯一检索列。此前缀应与在select中重命名列时指定的前缀相匹配,例如select <column> as <prefix><column>
。支持嵌套前缀。
还可以使用#[from_row(prefix)]
而不带值。在这种情况下,将使用下划线后的字段名。
可以通过将展开的类型包装在Option
中来实现外部连接。FromRow
的Option
实现将仍然需要所有列都存在,但如果所有列都是SQL null
值,则将产生一个None
。
use rusqlite_from_row::FromRow;
#[derive(FromRow)]
struct Todo {
id: i32,
name: String,
text: String,
#[from_row(flatten, prefix = "user_")]
author: User
#[from_row(flatten, prefix)]
editor: User
}
#[derive(FromRow)]
struct User {
id: i32,
name: String
}
// Rename all `User` fields to have `user_` or `editor_` prefixes.
let row = client
.query_one(
"
SELECT
t.id,
t.name,
t.text,
u.name as user_name,
u.id as user_id,
e.name as editor_name,
e.id as editor_id
FROM
todos t
JOIN
user u ON t.author_id = u.id
JOIN
user e ON t.editor_id = e.id
",
[],
Todo::try_from_row,
)
.unwrap();
重命名和转换
如果一个结构体包含一个名称与SQL列名不同的字段,可以使用 #[from_row(rename = "..")]
属性。
通常情况下,如果您有一个自定义包装类型,例如 struct DbId(i32)
,则需要实现 FromSql
才能在查询中使用它。一个简单的替代方法是实现 From<i32>
或 TryFrom<i32>
用于 DbId
,并在字段上添加 #[from_row(from = "i32")]
或 #[from_row(try_from = "i32")]
。
这将委托SQL转换到 <i32 as FromSql>
,然后将其转换为 DbId
。
use rusqlite_from_row::FromRow;
struct DbId(i32);
impl From<i32> for DbId {
fn from(value: i32) -> Self {
Self(value)
}
}
#[derive(FromRow)]
struct Todo {
// If the sqlite column is named `todo_id`.
#[from_row(rename = "todo_id", from = "i32")]
id: i32,
// If the sqlite column is `TEXT`, it will be decoded to `String`,
// using `FromSql` and then converted to `Vec<u8>` using `std::convert::From`.
#[from_row(from = "String")]
todo: Vec<u8>
}
依赖关系
~230–670KB
~16K SLoC