1个不稳定版本

0.0.0 2023年3月27日

#6#queried

MIT 协议

99KB

flagdb banner

Build Status Crates.io MIT licensed

Github仓库 | API文档

这是一个使用位(标志)列查询行的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许可证授权,不附加任何额外条款或条件。

无运行时依赖