6个版本

0.8.1 2024年5月28日
0.8.0 2024年5月27日
0.7.4 2023年9月14日
0.7.0 2023年7月16日
0.6.0 2023年3月5日

#95#code

每月 33 次下载
用于 airone

AGPL-3.0-or-later

22KB
374

Airone

Airone是一个Rust库,它提供了一个简单的内存数据库,该数据库在更新时持久化到只追加的事务文件,灵感来源于Aral Balkan的JSDB

简而言之,它充当一个Vec<T>,但任何更改都会自动快速保存到文件中。

名称与“空气”或“一”无关,它只是来自意大利语单词“Airone”,意为“鹳”。因此,它必须按照[aiˈrone]来读取。

  • 保存过程快速
  • 将所有数据保留在内存中以实现快速读取访问

此库将内存中的结构体列表持久化到磁盘。内存中数据的任何更改都会以快速的方式自动保存到磁盘,避免完整转储整个列表。

AironeDb对象类似于简单的结构体数组,但它们会在底层自动保存任何更改。以下是一个示例

let mut my_airone_array = AironeDb::<MyStruct>::new().unwrap();

my_airone_array.push(    //  <-- This command
    MyStruct{field1: 5}  //      saves the new data to disk
);                       //      automatically

my_airone_array
    .get_mut(0).unwrap() //  <-- Get a mutable proxy
                         //      to the element at index 0
    .set_field1(10);     //  <-- A setter method is generated automatically.
                         //      The change is persisted to file.

println!("{}",
    my_airone_array[0].field1 // you can access it by index
);

Rust到C库的桥梁已被移除,转而使用纯C库版本,它更小,简化了procmacro的可维护性,并且更容易将其包含在任何兼容C的项目中。您可以在https://gitlab.com/MassiminoilTrace/airone_c找到它。

使用场景

Airone是为了在以下所有先决条件都适用的情况下使用而开发的

  • 没有大数据:整个数据集应该适合内存
  • 数据集必须持久化到磁盘
  • 修改了一些数据后,需要以快速的方式将更改写入磁盘
  • 我们可以减慢程序启动时间,而不会有任何相关后果
  • 没有嵌套对象

以下是有两个良好的使用场景

  • 小型网络服务器:数据可能变化很快,完全可以放入内存中。启动可能会慢,只要服务器在运行时表现良好。这里提供了一个使用Airone和Rocket服务器的外部模板
  • 离线GUI/TUI程序:由于Airone的只追加文件架构,您可以将数据修改以非常快的速度存储,因此在保存过程中的界面冻结几乎不明显。这是一个非常简单的模板,它结合了Airone和Gtk3。

这些限制对于某些使用场景可能成为问题。现有的数据库添加了各种优化、缓存机制,非常复杂,以便能够处理如此大量的数据。
然而,当上述条件成立时,我们可以利用这些限制来简化源代码,使其更易于维护,并消除所有冗余软件。此外,限制对象嵌套使其与CSV风格文件兼容,确保您可以使用如grepawk之类的标准UNIX工具来操作数据。

上下文

Airone旨在帮助生产小技术,这是一种与硅谷模式相反的技术构建方式。小技术具有近乎零的数据收集、自由和开源结构以实现良好的透明度、不渴望指数级扩张、不希望在大数据处理时跟踪人们的行为,总体目标是保持简单和人性化。

文档

最基础的用法示例如下

use airone::prelude::*;

#[derive(AironeDbDerive)]
struct Foo
{
    pub field1: f64,
    pub field2: String,
    field3: Option<i32>
}

从这一点开始,您可以与类型为Foo的数据的Vec进行交互,并自动将任何更改持久化到文件。

let mut db: AironeDb<Foo> = AironeDb::new()?;
// Add an element
db.push(
    struct Foo{field1: 0.0, field2: "Abc".to_string(), field3: None}
    );
db.get(0); // <-- returns a read only Option<&Foo>

let m = db.get_mut(0).unwrap()  // <-- returns a convenient 
    .set_field1(0.5);           //     writable wrapper of Foo
                                //     in an Option<T>

// Remove element at index 0
db.remove(0);

有关完整的使用说明和实现细节,请参阅官方文档

版权

这不是公有领域,请务必尊重许可条款。您可以在COPYING文件中找到许可文本。

版权 © 2022,2023,2024 Massimo Gismondi

本程序是免费软件:您可以在GNU Affero通用公共许可证的条款和条件下重新分发和/或修改它,无论是许可证的第3版,还是(根据您的选择)任何较新版本。

本程序是免费分发的,希望它对您有用,但没有任何保证;甚至没有关于其适销性或特定用途的暗示保证。有关详细信息,请参阅GNU通用公共许可证。

您应该已收到GNU Affero通用公共许可证的一份副本。如果没有,请参阅https://gnu.ac.cn/licenses/

在此项目中使用的外部库

本项目使用一些外部库,具体请参阅Cargo.toml文件中所述。

  • AGPL-3.0-or-later: airone_derive
  • MIT / Apache-2.0: proc-macro2, quote, syn
  • (MIT / Apache-2.0) AND Unicode-DFS-2016: unicode-ident

本项目使用COPYING文件中的许可。

依赖

~255–700KB
~17K SLoC