1个不稳定版本
0.1.0 | 2022年11月23日 |
---|
#1027 在 WebAssembly
54KB
1K SLoC
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
特性,以便在将其保存到存储中之前将数据转换为 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宏自动为您的基本结构实现 Model
特性,并创建一个 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", "alice@example.com", &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 License,版本2.0(LICENSE-APACHE)
- MIT许可证(LICENSE-MIT)
。
贡献
除非您明确声明,否则任何有意提交以包含在您的工作中的贡献,根据Apache-2.0许可证定义,应按上述方式双许可,不附加任何其他条款或条件。
依赖项
~11–14MB
~267K SLoC