1个不稳定版本
0.0.0 | 2023年3月27日 |
---|
#6 在 #queried
99KB
这是一个使用位(标志)列查询行的Rust内存数据库。此数据库专为非常特定的用例设计,其中您具有大部分静态数据,通常在启动时加载并在查询时使用非常简单的过滤器。此类数据集可能很大,应该既快速又紧凑。
它主要是为了满足我们的需求而开发的,当然也有可行的替代方案。
欢迎贡献和反馈。
示例
只读数据库示例
use flagdb::flagdb;
flagdb! {
struct Employee {
id: u32,
name: String,
is_manager: bool,
is_admin: bool,
is_active: bool,
department: enum {
Sales,
Marketing,
Engineering,
HumanResources,
Accounting,
}
}
}
fn main() {
let db = EmployeeDB::with_capacity(100).extend(vec![
Employee {
id: 1,
name: "John".to_string(),
is_manager: true,
is_admin: false,
is_active: true,
department: Department::Sales,
},
Employee {
id: 2,
name: "Jane".to_string(),
is_manager: false,
is_admin: true,
is_active: true,
department: Department::Marketing,
},
Employee {
id: 3,
name: "Bob".to_string(),
is_manager: false,
is_admin: false,
is_active: false,
department: Department::Engineering,
},
]);
let active_managers: Vec<String> = db.query()
.is_manager()
.is_active()
.run()
.map(|employee| employee.name)
.collect();
assert_eq!(active_managers, vec!["John".to_string()]);
}
上面的示例展示了如何轻松地创建一个内存数据库,同时仍然功能强大且易于使用。
内部发生了什么?在高级别上,以下内容被生成(使用cargo expand
查看完整生成的代码)
#[derive(Debug, flagdb::Serialize, flagdb::Deserialize)]
struct Employee {
pub id: u32,
pub name: String,
pub is_manager: bool,
pub is_admin: bool,
pub is_active: bool,
pub department: EmployeeDepartment,
}
#[derive(Debug, flagdb::Serialize, flagdb::Deserialize)]
enum EmployeeDepartment {
Sales,
Marketing,
Engineering,
HumanResources,
Accounting,
}
#[derive(Debug)]
struct EmployeeDB {
employees: Vec<Employee>,
is_manager: flagdb::BitVec,
is_admin: flagdb::BitVec,
is_active: flagdb::BitVec,
departments: flagdb::BitMap<EmployeeDepartment>,
}
struct EmployeeDBQueryBuilder<'a> {
db: &'a EmployeeDB,
...
}
impl EmployeeDB {
fn new() -> Self { ... }
fn with_capacity(capacity: usize) -> Self { ... }
fn extend(&mut self, employees: impl IntoIterator<Item = Employee>) { ... }
fn query(&self) -> EmployeeDBQueryBuilder { ... }
fn iter(&self) -> impl Iterator<Item = &Employee> {
self.employees.iter()
}
}
impl EmployeeDBQueryBuilder<'_> {
fn is_manager(&mut self) -> &mut Self { ... }
fn is_admin(&mut self) -> &mut Self { ... }
fn is_active(&mut self) -> &mut Self { ... }
fn department(&mut self, department: EmployeeDepartment) -> &mut Self { ... }
fn run(self) -> impl Iterator<Item = &Employee> { ... }
}
impl Iterator for EmployeeDB<'_> {
type Item = &'_ Employee;
fn next(&mut self) -> Option<Self::Item> { ... }
}
impl IntoIterator for EmployeeDB {
type Item = Employee;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.employees.into_iter()
}
}
修改示例
如果您需要修改数据库,您可以通过一些更改来实现。
首先,flagdb创建需要稍作修改
flagdb! { struct Employee { #flagdb::key id: u32, name: String, is_manager: bool, is_admin: bool, is_active: bool, department: enum { Sales, Marketing, Engineering, HumanResources, Accounting, } } }
注意在id
字段上使用#[flagdb::key]
属性,这将在内部确保我们在实际的EmployeeDB
结构体中生成一个flagdb::FxHashMap<u32, usize>
属性。
然后我们可以按照以下方式修改先前查询的员工
db.get_mut(1).unwrap().is_manager = false; // John is no longer a manager
但我们也可以查询可修改的内容,而不进行修改
// fire all the managers
let active_managers: Vec<&mut Employee> = db.mutate()
.is_manager()
.is_active()
.run()
.map(|employee| employee.is_active = false);
安全性
这些crate使用#![forbid(unsafe_code)]
来确保所有内容都是100%安全Rust实现的。
贡献
🎈 感谢您为改进项目做出的贡献!我们非常高兴有您的参与!我们有一个贡献指南,帮助您参与flagdb
项目。
许可证
本项目采用MIT许可证。
贡献
除非您明确表示,否则您提交给flagdb
的任何有意贡献均应按MIT许可证授权,不附加任何额外条款或条件。