5个版本 (3个破坏性更新)
新 0.4.0 | 2024年8月13日 |
---|---|
0.3.1 | 2024年8月12日 |
0.3.0 | 2024年8月11日 |
0.2.0 | 2024年8月10日 |
0.1.0 | 2024年8月7日 |
#8 in #redb
每月下载量 551
在 redb_model 中使用
21KB
448 行
Redb模型
用于生成redb
表定义和DTO对象转换方法/实现的推导宏。
功能
该软件包旨在统一数据库条目DTO定义和redb::TableDefinition
。使用#[derive(Model)]
装饰结构体将为类型实现Model
,定义redb::TableDefinition
作为关联常量,并为类型生成辅助方法。
示例
#[derive(Model)]
struct User {
#[entry(position(key))]
id: u32,
#[entry(position(value))]
name: String,
#[entry(position(value))]
email: String,
}
let user = User {
id: 0,
name: "User".to_owned(),
email: "[email protected]".to_owned(),
};
let txn = db.begin_write().unwrap();
{
let mut table = txn.open_table(User::DEFINITION).unwrap();
let (k, v) = user.as_values();
table.insert(k, v).unwrap();
}
txn.commit().unwrap();
指定键和值
键和值通过使用#[entry(position(...))]
装饰表字段来指定,通过将key
或value
传递给内部字段。复合键/值将组合成一个元组。
#[derive(Model)]
struct User {
#[entry(position(key))]
uuid: [u8; 16],
#[entry(position(value))]
username: String,
#[entry(position(value))]
email: String,
}
let user_key = [0; 16];
let user_value = ("my_name".to_string(), "[email protected]".to_string());
let user = User::from_values((user_key, user_value));
let (k, v) = user.into_values();
// Only the value is a tuple for this model.
assert_eq!(k, [0; 16]);
assert_eq!(v, ("my_name".to_string(), "[email protected]".to_string()));
指定表名
表名默认为(区分大小写)的结构名称。可以通过在结构体上装饰 #[model(name = "...")]
属性来覆盖。
#[derive(Model)]
#[model(name = "user_table")]
struct User {
#[entry(position(key))]
uuid: [u8; 16],
#[entry(position(value))]
username: String,
}
assert_eq!(User::DEFINITION.name(), "user_table");
类型转换
Model
特性的生成实现提供了实例化、借用和获取模型 DTO 的键/值对的方法。通过在结构体上装饰 #[model(impl_from)]
将进一步实现 From<T>
,将 T
映射到 from_values(T)
和 from_guards(T)
方法。
#[derive(Model)]
#[model(impl_from)]
struct User {
#[entry(position(key))]
uuid: [u8; 16],
#[entry(position(value))]
username: String,
#[entry(position(value))]
email: String,
}
let user_key = [0; 16];
let user_value = ("my_name".to_string(), "[email protected]".to_string());
let user: User = ((user_key, user_value)).into();
实现细节
以下是一些关于实现的通用说明。
String
表定义
redb_model
将用 &str
替换 String
用于表定义。这样,复合(元组)变量可以借用并传递给数据库处理器而不需要对 DTO 进行解构。这目前使用 String
是不可能的。
const TABLE: TableDefinition<(String, String), ()> = TableDefinition::new("table");
let string_0 = "string_0".to_string();
let string_1 = "string_1".to_string();
let txn = db.begin_write().unwrap();
let mut table = txn.open_table(TABLE).unwrap();
// This doesn't work.
table.insert((&string_0, &string_1), ());
// Neither does this.
table.insert((string_0.as_str(), string_1.as_str()), ());
```rust
### Unit type values
The unit type `()` must be passed if no value is defined.
```rust
#[derive(Model)]
#[model(name = "outbound_edge")]
struct Edge {
#[entry(position(key))]
source: [u8; 16],
#[entry(position(key))]
target: [u8; 16],
}
let k = ([0; 16], [1; 16]);
let v = ();
let e = Edge::from_values((k, v));
变量排序
所有复合键/值变量按定义的顺序组合为一个元组。这是预期的,但在有理由的情况下可以更改。
Model
定义和 redb::TableDefinition
redb::TableDefinition
使用 'static
引用 Model
中定义的类型,除了 String
使用一个 'static
字符串切片。这是为了确保调用 as_values
返回适合数据库调用的引用。
许可证:MIT OR Apache-2.0
依赖关系
~1.2–1.7MB
~40K SLoC