4 个版本

0.2.3 2021年1月3日
0.2.2 2021年1月2日
0.2.1 2020年12月30日
0.2.0 2020年12月28日

#2414数据库接口

MIT/Apache

40KB
893

RedDb

Actions Status Crates.io

RedDb 是一个异步、快速、轻量级的嵌入式内存文档数据库,具有在多种 serde 兼容格式(当前为 ron 和 json,未来为 bindcode 和 cbor)中的持久化功能。RedDb 使用 Tokio,以便提供易于使用的异步 API 进行 插入查找更新删除 数据。

快速入门

将 RedDb 添加到您的 Cargo.toml,指定您想使用的序列化器

[dependencies.RedDb]
version = "0.2.3"
features = ["ron_ser"] # Ron serialization / deserialization
features = ["json_ser"] # Json serialization / deserialization

use reddb::{Document, RonDb};

#[derive(Clone, Serialize, PartialEq, Deserialize)]
struct MyStruct {
  foo: String,
}

#[tokio::main]
async fn main() -> Result<()> {
  // RedDb with RON persistance for MyStruct structs
  let db = RonDb::new::<MyStruct>("my.db").unwrap();
  let my_struct = MyStruct {
    foo: String::from("hello")
  };

  // Insert data
  let doc = db.insert_one(my_struct).await?;
  // Find by id
  let my_doc: Document<MyStruct> = db.find_one(&doc._id).await?;
  // Find all records equal to my_struct
  let my_docs : Vec<Document<MyStruct>> = db.find(&my_struct).await?;
  Ok(())
}

为什么

RedDb 是一个原本用 NodeJs 编写的侧项目的迁移版本,该项目旨在存储内存中的对象(具有 hd 持久化)并在其上进行搜索。

何时

如果您正在寻找经典的键/值存储,您会发现更好的选择,因为 RedDb 不是一个键/值存储(RedDb 使用自动生成的 Uuids)。您可以将任何类型的数据存储,因为数据将被处理为 通用,但 RedDb 被设计为存储对象/结构体,并在这些结构体上执行基本搜索操作。也就是说,如果您正在寻找一个轻量级且易于使用的内存数据存储,具有持久化功能,RedDb 可以是一个不错的选择!

API

数据

数据以不同的 serde 兼容格式(json、ron、yaml)序列化和反序列化,并包装到 Document 结构体中,如下所示

pub struct Document<T> {
  pub _id: Uuid,
  pub data: T,
  pub _st: Status,
}

由于数据字段是通用的,您可以存储任何类型的数据。如您在 API 中所见,Document 是大多数操作的默认返回类型。

持久化

RedDb 的持久化使用追加格式(AOF),因此所有写操作(插入、更新、删除)都被添加到数据库文件的末尾。每次您在应用程序中启动数据库时,数据库都会自动压缩,每个对象/记录仅占用一行。

API提供类似批量操作的写操作(插入、更新和删除),这些操作由于hd同步操作而更快地持久化。请使用API上的*_one()方法来代替。

插入数据

插入数据非常简单。如果你想插入一个文档,使用insert_one方法

插入一个

#[derive(Clone, Serialize, PartialEq, Deserialize)]
struct MyStruct {
  foo: String,
}

let my_struct = MyStruct {
  foo: String::from("hello")
};

let doc: Document<TestStruct> = store.insert_one(my_struct).await?;
println!("{:?}", doc._id);
// 94d69737-4b2e-4985-aaa1-e28bbff2e6d0

插入

如果你想要插入一组数据,使用insert()方法比迭代insert_one()方法更合适,也更快,因为AOF持久化的特性。

let my_docs = vec![MyStruct {
  foo: String::from("one"),
},
MyStruct {
  foo: String::from("two"),
}];

let docs: Vec<Document<MyStruct>> = db.insert(my_docs).await?;

查找数据

有两种方式可以找到你的数据。通过它的ID或者查找数据库中符合你查询的数据。

查找一个

通过ID执行搜索。

let my_struct = MyStruct {
  foo: String::from("hello")
};

let inserted_doc = db.insert_one(my_struct).await?;
let doc: Document<MyStruct> = db.find_one(&inserted_doc._id).await?;

查找

在数据库中查找符合你查询条件的数据。

let one = MyStruct {
  foo: String::from("Hello"),
};

let two = MyStruct {
  foo: String::from("Hello"),
};

let three = MyStruct {
  foo: String::from("Bye"),
};


let many = vec![one.clone(), two.clone(), three.clone()];
let inserted_doc : Document<MyStruct> = db.insert(many).await?;
let docs: Vec<Document<MyStruct>> = db.find(&one).await?;

更新数据

更新数据非常简单。你可以更新数据

更新一个

使用它的ID作为搜索参数更新一条记录。

let my_struct = MyStruct {
  foo: String::from("hello")
};

let new_value = MyStruct {
  foo: String::from("bye"),
};

let inserted_doc = db.insert_one(my_struct).await?;
let updated: bool = db.update_one(&inserted_doc._id, new_value)).await?;

更新

你可以更新数据库中所有符合你查询条件的数据。更新将返回更新文档的数量。

let search = MyStruct {
  foo: String::from("hello")
};

let new_value = MyStruct {
  foo: String::from("bye"),
};

let updated: usize = store.update(&search, &new_value).await?;

删除数据

删除一个

通过它的ID删除一条记录。

let my_struct = MyStruct {
  foo: String::from("hello")
};

let doc = db.insert_one(my_struct).await?;
let deleted : bool = db.delete_one(&doc._id)).await?;

删除

类似于update方法,此方法将查找数据库中符合你查询条件的数据,然后删除它。

let search = MyStruct {
  foo: String::from("hello")
};

let deleted = store.delete(&search).await?;
println!("{:?}", updated);
// 1

许可证

此库受

依赖项

~6.5MB
~110K SLoC