1 个不稳定版本
0.1.0 | 2022年11月23日 |
---|
#6 在 #idb
用于 deli
27KB
457 行
deli
Deli 是对 idb
创建的便利包装,用于在浏览器中使用 derive 宏轻松创建和管理 indexed db 中的对象存储。
用法
要使用 deli
,您需要在您的 Cargo.toml
中添加以下内容
[dependencies]
deli = "0.1"
deli
旨在用于使用 webassembly 的浏览器。因此,请确保使用 --target wasm32-unknown-unknown
编译您的项目。或者,您可以在您的 .cargo/config.toml
中添加以下构建配置
[build]
target = "wasm32-unknown-unknown"
示例
定义一个 Model
第一步是使用 Model
derive 宏定义您的数据模型。您还需要为您的模型实现 serde::Serialize
和 serde::Deserialize
trait,以便在将其保存到存储之前将数据转换为 json
。
use deli::Model;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Model)]
pub struct Employee {
#[deli(auto_increment)]
pub id: u32,
pub name: String,
#[deli(unique)]
pub email: String,
#[deli(index)]
pub age: u8,
}
Model
derive 宏会自动为您 struct 实现 Model
trait 并创建一个 Store
,用于访问和写入存储中的数据。
容器属性
-
#[deli(name)]
:在索引数据库中,默认情况下,在创建数据库时会创建一个名为结构体名称的新对象存储(在上面的例子中,它将在索引数据库中创建一个名为Employee
的对象存储)。要更改默认对象存储名称,请使用#[deli(name = "your_object_store_name")]
。 -
#[deli(store_name)]
:默认情况下,派生宏将创建一个名为<ModelName>Store
的结构体(在上面的例子中,它将创建一个EmployeeStore
结构体)。要更改默认名称,请使用#[deli(store_name = "YourStoreName")]
。
字段属性
#[deli(key)]
:定义对象存储的主键路径。#[deli(auto_increment)]
:定义具有auto_increment
值的对象存储的主键路径(意味着#[deli(key)]
)。#[deli(index)]
:为字段创建索引。#[deli(unique)]
:为字段创建唯一索引(意味着#[deli(index)]
)。#[deli(multi_entry)]
:为字段创建一个多入口索引(隐含#[deli(index)]
)。#[deli(rename)]
:重命名对象存储中的字段。注意,这应与serde
序列化保持一致。例如,如果您使用#[serde(rename_all = "camelCase")]
,您需要适当地重命名deli
字段以与serde序列化保持同步。
创建数据库
下一步是创建一个新的Database
实例,并将其与模型注册。
use deli::{Database, Error};
async fn create_database() -> Result<Database, Error> {
let database = Database.builder("test_db", 1).register_model::<Employee>().await?;
}
开始事务
一旦创建了Database
实例,您就可以使用事务开始读取和写入数据库数据。
use deli::{Database, Error, Transaction};
fn create_read_transaction(database: &Database) -> Result<Transaction, Error> {
database.transaction().with_model::<Employee>().build()
}
fn create_write_transaction(database: &Database) -> Result<Transaction, Error> {
database.transaction().writable().with_model::<Employee>().build()
}
您可以通过添加多个.with_model::<Model>()
调用,将多个模型添加到事务中。
读取和写入模型存储数据
一旦您有了模型的交易,您就可以读取或写入该模型的数据。
use deli::{Error, Model, Transaction};
async fn add_employee(transaction: &Transaction) -> Result<u32, Error> {
Employee::with_transaction(transaction)?.add("Alice", "[email protected]", &25).await
}
async fn get_employee(transaction: &Transaction, id: u32) -> Result<Option<Employee>, Error> {
Employee::with_transaction(transaction)?.get(&id).await
}
async fn get_all_employees(transaction: &Transaction) -> Result<Vec<Employee>, Error> {
// NOTE: Here `..` (i.e., `RangeFull`) means fetch all values from store
Employee::with_transaction(transaction)?.get_all(.., None).await
}
async fn get_employees_with_bounds(
transaction: &Transaction,
from_id: u32,
to_id: u32,
) -> Result<Vec<Employee>, Error> {
Employee::with_transaction(transaction)?.get_all(&from_id..=&to_id, None).await
}
提交事务
完成所有写入后,您可以提交事务
async fn commit_transaction(transaction: Transaction) -> Result<(), Error> {
transaction.commit().await
}
请注意,commit()
通常不需要调用——当所有未解决的请求得到满足且没有新的请求时,事务会自动提交。
此外,当使用长生命周期的索引数据库事务时,请注意其行为可能会根据浏览器而改变。例如,在事件循环中进行IO(网络请求)时,事务可能会自动提交。
许可证
根据您的选择,许可协议为
- Apache许可证2.0版本(LICENSE-APACHE)
- MIT许可证(LICENSE-MIT)
自由选择。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的您有意提交以包含在工作中的任何贡献,应按上述方式双许可,无需附加条款或条件。
依赖关系
~2MB
~42K SLoC