8个版本 (4个重大更新)
0.5.2 | 2020年4月25日 |
---|---|
0.5.1 | 2019年9月5日 |
0.5.0 | 2019年8月21日 |
0.4.0 | 2019年8月1日 |
0.1.0 | 2019年4月16日 |
#2364 in 数据库接口
每月下载量 35次
37KB
927 行
描述
rql
是一个Rust的内存虚拟数据库。它提供了管理虚拟关系表及其模式的功能。
更多信息,请查看文档。
lib.rs
:
描述
RQL (Rusty Query Language) 是一个库,旨在将类似SQL的逻辑引入Rust。然而,请注意,这里没有传统的数据库,只有一些应用于迭代器和哈希表的特性和适配器。
重要提示
rql
不提供真正的数据库。所有数据都存储在内存中。这个虚拟数据库可以通过从serde
进行序列化和反序列化来保存到磁盘和从磁盘加载。支持多种序列化协议,以便您可以选择一个适合您速度、大小和向后兼容性需求的一个。
模式
要使用rql
数据库,您必须首先定义一些模式。每个表都由一个表示单个条目的结构体定义。在这个例子中,我们将定义三个表:User,Group和Member。
use rql::prelude::*;
#[derive(Serialize, Deserialize)]
struct User {
name: String,
age: u8,
}
#[derive(Serialize, Deserialize)]
struct Group {
name: String,
}
#[derive(Serialize, Deserialize)]
struct Member {
user_id: Id<User>,
group_id: Id<Group>,
permission: bool,
}
唯一ID字段不是必需的,因为每个条目都会自动分配一个唯一标识符。对其他表中条目的引用用Id<T>
表示。
使用schema!
宏来创建实际的模式
schema! {
MySchema {
user: User,
group: Group,
member: Member,
}
}
数据库操作
以下是一些与数据库交互的简单方法。
// Create a new database with the previously defined schema
// We pass a folder name for the database files as well as a representation type
let db = MySchema::new("test_database_example", HumanReadable).unwrap();
// Insert values into the database
// Insertion returns the new row's id
let dan = db.user_mut().insert(User { name: "Dan".into(), age: 25 });
let steve = db.user_mut().insert(User { name: "Steve".into(), age: 39 });
let mary = db.user_mut().insert(User { name: "Mary".into(), age: 31 });
let admin = db.group_mut().insert(Group { name: "Admin".into() });
let normal = db.group_mut().insert(Group { name: "Normal User".into() });
db.member_mut().insert(Member { user_id: dan, group_id: admin, permission: true });
db.member_mut().insert(Member { user_id: steve, group_id: normal, permission: true });
db.member_mut().insert(Member { user_id: mary, group_id: normal, permission: false });
// Data can easily be looked up by id
db.user_mut().get_mut(dan).unwrap().age += 1;
let dan_age = db.user().get(dan).unwrap().age;
assert_eq!(dan_age, 26);
// Data can be selected from a table
let ages: Vec<u8> = db.user().select(|user| user.age).collect();
// Use `wher` to filter entries
let can_run_for_president: Vec<String> =
db.user()
.wher(|user| user.age >= 35)
.select(|user| user.name.clone())
.collect();
// Table intersections are done using `relate`
// A function relating the tables is required
for (user, permission) in db.user()
.relate(
&*db.member(),
|user, member| user.id == member.user_id && member.group_id == normal
)
.select(|(user, member)| (&user.data.name, member.permission)) {
println!("{} is a normal user with permission = {}", user, permission);
}
// Rows can be updated with `update`
for mut user in db.user_mut().update() {
user.age += 1;
}
// Rows can be deleted in a few ways
// By id
db.user_mut().delete_one(steve);
// With a where clause
db.member_mut().delete_where(|member| member.permission);
// With an iterator over ids
db.user_mut().delete_iter(|_| vec![dan, mary]);
// Changes to the database are automatically saved, so they can be loaded again
let db_copy = MySchema::new("test_database_example", HumanReadable).unwrap();
assert_eq!(db.user().len(), db_copy.user().len() );
assert_eq!(db.group().len(), db_copy.group().len() );
assert_eq!(db.member().len(), db_copy.member().len());
依赖关系
~2.8–4MB
~79K SLoC