22个稳定版本

3.2.1 2023年10月23日
3.2.0 2023年10月22日
2.0.2 2023年10月16日
1.4.1 2022年12月4日
1.3.2 2022年9月19日

#6#front-matter

MITGPL-3.0 许可协议

37KB
791

锡耶纳

锡耶纳是Rust的数据提供者无关的ORM,使您能够轻松使用自定义数据存储,同时拥有查询引擎的所有优点。

锡耶纳内置了一个平面文件数据提供者LocalProvider,支持YAML和FrontMatter文件,但您可以轻松通过实现StoreProvider特质来创建自己的数据提供者。

安装

将以下内容添加到您的Cargo.toml文件中

siena = "3.0.0"

更新日志

要查看更改,请查看更新日志

使用方法

创建存储

使用锡耶纳的第一步是创建存储。存储是具有数据提供者的锡耶纳实例。数据提供者是实现StoreProvider特质(因此您可以创建自己的!)的任何内容。锡耶纳附带LocalProvider提供者,它在本地文件系统上运行。

示例

use siena::providers::local::LocalProvider;
use siena::siena::siena;

fn main() {
    let provider = LocalProvider { directory: "./path".to_string() };
    let store = siena(provider);
}

检索记录

记录放在集合中。集合是您的存储中的一个目录。假设您有一个名为"blog-posts"的集合,您可以这样检索它们

let posts = store.collection("blog-posts").get_all();

您也可以通过get_first()获取第一条记录或通过.get_last()获取最后一条记录。

筛选记录

您可以使用多个when_*方法来筛选记录。是的,您可以根据需要链式调用它们。

when_is

要按等于给定值的记录键筛选记录,您可以使用when_is方法,如下所示

let posts = store
    .collection("blog-posts")
    .when_is("status", "published")
    .get_all();

when_is_not

同样,要按不等于给定值的记录键筛选记录,您可以使用when_isnt方法

let posts = store
    .collection("blog-posts")
    .when_is_not("status", "published")
    .get_all();

when_has

要按记录键的存在筛选记录,您可以使用when_has方法,如下所示

let posts = store
    .collection("blog-posts")
    .when_has("status")
    .get_all();

when_has_not

同样,要按记录键不存在筛选记录,您可以使用when_hasnt方法

let posts = store
    .collection("blog-posts")
    .when_has_not("status")
    .get_all();

when_matches

通过正则表达式模式匹配的记录键来过滤记录,您可以使用when_matches方法,如下所示

let posts = store
    .collection("blog-posts")
    .when_matches("date", r"2022\-09")
    .get_all();

没有与when_matches相反的方法,因为正则表达式允许您自己完成这个操作。

排序记录

您可以使用sort方法对记录进行排序,如下所示

use siena::siena::{RecordSortOrder};

let posts = store
    .collection("blog-posts")
    .sort("date", RecordSortOrder::Desc)
    .get_all();

可用的排序方式有

  • RecordSortOrder::Desc
  • RecordSortOrder::Asc

限制记录

要限制结果,请使用limit方法

let posts = store
    .collection("blog-posts")
    .limit(10)
    .get_all();

偏移记录

要偏移结果,请使用offset方法

let posts = store
    .collection("blog-posts")
    .offset(10)
    .get_all();

分页

通过结合limitoffset方法,您可以轻松创建分页,例如

let page = 2;
let posts_per_page = 10;

let posts = store
    .collection("blog-posts")
    .offset((page - 1) * posts_per_page)
    .limit(posts_per_page)
    .get_all();

或者,简单地使用paginate方法,它会为您完成这项工作,如下所示

let posts = store
    .collection("blog-posts")
    .paginate(2, 10)
    .get_all();

更新记录

您可以通过set方法来更新查询的结果。无论您有一条记录还是多条记录,它都会更新与您的查询匹配的任何内容。

例如

let posts = store
    .collection("blog-posts")
    .set(Vec::from([("status", "private")]));

这将通过将status更新为private来更新blog-post集合中的所有记录。

而以下示例

let posts = store
    .collection("blog-posts")
    .when_is("status", "public")
    .set(Vec::from([("status", "private")]));

将只更新所有状态为public的记录,将其更改为private

创建记录

create方法用于创建新记录。然而,请注意,记录只有在您使用set方法添加一些数据后才会持久化。只有set方法是写入数据的方法。create方法仅在内存中创建记录,以便set方法知道在哪里写入数据。

示例

store
    .create("blog-posts", "hello-world")
    .set(Vec::from([("title", "Hello, World.")]));

create方法接受两个参数,集合名称和记录ID,该ID必须对该集合是唯一的,否则它将覆盖现有记录。

删除记录

delete方法用于删除与查询匹配的所有记录,例如,如果您想删除所有状态为“草案”的记录,您将运行以下操作

store
    .collection("blog-posts")
    .when_is("status", "draft")
    .delete();

提供者

LocalProvider

LocalProvider是一个在本地文件系统上工作的提供者。它支持YAML和Markdown(FrontMatter)文件。在Markdown文件的情况下,返回的Record将具有contentcontent_raw字符串条目,分别对应于渲染的HTML和原始Markdown。

支持的数据类型有

  • String
  • usize
  • bool
  • HashMap<String、RecordData>
  • Vec<RecordData>

自定义提供者

您可以通过实现StoreProvider特质来创建自己的提供者。该特质有三个您需要实现的方法

pub trait StoreProvider {
    fn retrieve(&self, name: &str) -> Vec<Record>;
    fn set(&self, records: Vec<Record>, data: Vec<(&str, &RecordData)>) -> Vec<Record>;
    fn delete(&self, records: Vec<Record>);
}

retrieve函数

此函数应接受一个数据集合的name,例如posts,并返回该集合的所有Record

set函数

此函数应接受一个 Vec<Record> 和一个 Vec<(&str, &RecordData)> 并返回一个 Vec<Record>。该 Vec<Record> 是您要更新的记录,而 Vec<(&str, &RecordData)> 是您想要用于更新的数据。其中 &str 是数据的键,而 &RecordData 是值。

delete 函数

此函数应接受一个 Vec<Record> 并删除它们。

依赖关系

~7-17MB
~236K SLoC