5 个版本 (3 个破坏性更新)
0.6.1 | 2023年10月2日 |
---|---|
0.5.1 | 2023年9月20日 |
0.5.0 | 2023年9月19日 |
0.4.0 | 2023年8月31日 |
0.3.0 | 2023年8月11日 |
#377 在 文件系统
每月 39 次下载
325KB
8K SLoC
Ghee:在 Btrfs 上数据变更管理的一层薄薄的外壳,使用 Linux 扩展属性(xattrs)
使用 Linux 扩展属性(xattrs)管理数据的最佳方式,纯 Rust 编写,由美味、纤维丰富的开源代码组成。
Ghee 提供了用于操作单个文件上的 xattrs 的工具,以及将文件系统作为文档数据库进行工作的工具,其中文件系统路径作为主键,扩展属性作为字段。
可以使用类似 Git 风格的提交来管理 Ghee 表中的数据,这些提交作为 Btrfs 子卷和只读快照实现。
这样,Ghee 利用 Btrfs 的写时复制(CoW)特性,有效地存储增量,即使在大型二进制块中也是如此。
许可证
此软件仅根据 GPL 版本 3 许可。
约定
Ghee 以一致的方式解析扩展属性名称。任何不以 trusted
、security
、system
或 user
命名空间开头的 xattr 将默认为 user
命名空间。例如,xattr trusted.uptime
保持不变,而 uptime
将变为 user.uptime
。
如果可能,扩展属性值将被解析为 f64
数字;否则,它们将被解释为字符串。
REPL
没有参数运行 ghee
将进入一个读取-评估-打印循环(REPL),允许流畅的命令输入
$ ghee
Ghee 0.6.0
ghee$ set ./test -s test=1
等等。
子命令
Ghee 通过一组子命令操作,每个子命令都有一个主要功能。运行 ghee --help
列出它们,并运行 ghee $SUBCMD --help
获取每个子命令的用法信息。
以下列出了每个子命令的示例
移动
将 xattr 值从一个路径移动到另一个路径。
ghee mv path1.txt path2.txt
:将 path1.txt 上的所有 xattr 移动到 path2.txtghee mv -f id path1.txt path2.txt
:将 xattrid
从 path1.txt 移动到 path2.txtghee mv -f id -f url path1.txt path2.txt
:将 xattrsid
和url
从 path1.txt 移动到 path2.txt
复制
从一个路径复制 xattr 值到另一个路径。
ghee cp path1.txt path2.txt
:复制 path1.txt 中的所有 xattr 到 path2.txtghee cp -f id path1.txt path2.txt
:将 xattrid
从 path1.txt 复制到 path2.txtghee cp -f id -f url path1.txt path2.txt
:将 xattrsid
和url
从 path1.txt 复制到 path2.txt
删除
默认情况下,递归删除 xattr 值。
ghee rm path.txt
:从 path.txt 删除所有 xattrghee rm dir
:从 dir 及其所有子目录中删除所有 xattrghee rm --flat dir
:仅从 dir 中删除所有 xattr,不包括其子目录ghee rm -f id path.txt
:从 path.txt 删除 xattrid
ghee rm -f id -f url path1.txt path2.txt path3.txt
:从 path1.txt、path2.txt 和 path3.txt 中删除 xattrsid
和url
ghee rm -f name dir
:从 dir 及其所有子目录中删除 xattrname
设置
默认情况下,递归设置 xattr 值。
ghee set -s id=123 path1.txt
:将 path1.txt 上的 xattrid
设置为值123
ghee set -s name=Jama dir
:将 dir 及其所有子目录上的 xattrname
设置为值"Jama"
ghee set -s name=Amira --flat dir
:仅将 dir 上的 xattrname
设置为值"Amira"
,不包括其子目录ghee set -s id=123 -s url=http://example.com path1.txt path2.txt path3.txt
:将 path1.txt、path2.txt 和 path3.txt 上的 xattrid
设置为值123
,将 xattrurl
设置为值"http://example.com"
获取
递归地获取并打印一个或多个路径的 xattr 值。
默认情况下,get
子命令输出一个以制表符分隔的表,列顺序为 path
、field
、value
。值字节作为原始数据写入 stdout,不进行解码。
这排除了 user.ghee
前缀,除非传递了 -a --all
。
要取消递归默认值,请使用 --flat
。
ghee get dir
:以原始(未解码)的TSV格式打印目录dir
以及所有子文件和子目录的所有xattr。ghee get -f id path1.txt
:以原始(未解码)的TSV格式打印路径1.txt上的xattrid
和其值。ghee get -f id -f url path1.txt path2.txt path3.txt
:以原始(未解码)的TSV格式打印路径1.txt、path2.txt 和 path3.txt 上的xattrid
和url
及其相应的值。
get
命令还可以输出JSON - 在这种情况下,值以UTF-8解码,解码失败时填充默认代码点。
ghee get -j --flat dir
:以UTF-8解码的JSON格式打印目录dir
本身的所有xattr,但不包括其子目录。ghee get -j -f id path1.txt
:以UTF-8解码的JSON格式打印路径1.txt上的xattrid
和其值。ghee get -j -f id -f url path1.txt path2.txt path3.txt
:以JSON格式打印路径1.txt、path2.txt 和 path3.txt 上的xattrid
和url
及其相应的值。
通过添加 --where
(或 -w
),可以提供类似SQL WHERE的子句来选择要包含在输出中的文件。例如,ghee get -w age >= 65 ./patients
将选择目录 ./patients
下所有 user.age
属性为65或更大的文件。
在 get
输出中始终忽略嵌套索引,尽管当指定WHERE样式谓词时,它们将适当用作遍历的快捷方式。
初始化
使用指定的主键将目录初始化为表,可选地从JSON插入记录,每行独立解析 - 请参阅存储库中的 people.json
示例。
示例
ghee init -k name ./people
:将./people
目录标记为主键为name
的表。ghee init -k state -k id ./people-by-state-and-id
:将./people-by-state-and-id
目录标记为主键为 [state
,id
] 的表。ghee init -k sauce ./pizza < ./pizzas.json
:将./pizza
目录标记为表,以sauce
为主键,从./pizzas.json
导入记录
创建
与init
完全相同,但首先创建目录,如果已存在则报错。
插入
将JSON格式的记录插入到表中。
记录从stdin逐行读取。
ghee ins ./people < ./people.json
:将./people.json
中的记录插入到./people
的表中,按其主键索引ghee ins ./people ./people.json
:与上述相同,但不需要shell进行重定向
删除
从表中删除记录。
它们将从所有表索引中取消链接。
要删除的记录通过提供主键的组成部分或SQL风格的WHERE子句来指定。
ghee del ./people Von
:因为表的主键是name
,从./people
及其所有索引中删除name=Von
的记录ghee del ./people -w name=Von
:如上删除./people/Von
,从所有索引中取消链接
索引
对表进行索引。
当Ghee将目录作为数据库表处理时,每个文件作为关系型“记录”,其主键由其位于表目录下的子路径推断。
每个文件的扩展属性作为关系型属性。
Ghee创建的表目录还包含一个特殊的xattr user.ghee.tableinfo
,其中存储表的主键和相关索引(包括自身)。
如果没有提供索引位置,它将被放置在索引表的默认路径下。
示例
-
ghee idx -k name ./people ./people-by-name
:递归地将./people
的内容重新索引到新目录./people-by-name
中,主键来自xattrname
,并将文件硬链接到./people
中相应的文件。这意味着
./people-by-name
目录的文件将使用xattrname
中定义的人的名字作为文件名。user.ghee.tableinfo
xattr为./people
记录./people-by-name
作为相关索引,反之亦然:./people-by-name
的user.ghee.tableinfo
xattr记录./people
作为相关索引。使用可用的索引,将有机会加速查询,如
get
和del
。 -
ghee idx -k region -k name --s ./people-by-name ./people-by-region-and-name
:递归地重新索引./people-by-name
的内容,将其放入新的目录./people-by-region-and-name
,其中主键是 xattrregion
和 xattrname
的复合(按此顺序),文件通过./people-by-name
中的硬链接与./people
中的对应文件硬链接。两个目录的
user.ghee.tableinfo
xattr 将被更新以反映它们的关系。
列表
类似于 ls
命令,列出目录内容,但以 Ghee 的视角进行注释。
每个路径都被标记为表或记录。对于表,给出主键。
ghee ls
:列出当前目录的内容ghee ls example
:列出 ./example 的内容
提交
将表当前状态存储在 Btrfs 快照中,由 UUID 标识。
可选地,可以提供描述自上次快照以来(如果有)所做的更改的消息。
ghee commit-m"更新 README.md"
输出提交的 UUID。
日志
显示过去的提交。
ghee log
:列出当前表的所有过去提交
触摸
类似于 Unix 的 touch
命令,在指定的路径创建一个空文件;如果路径是 Ghee 表的一部分,将根据路径推断 xattr 并写入新文件。
这是向新表添加新记录的便捷方式。
使用 -p / --parents
,将创建父目录。
ghee touch /pizza/pepperoni
:在/pizza/pepperoni
创建一个空文件,设置 xattrtopping
为pepperoni
,因为/pizza
表的键是topping
。
恢复
将路径恢复到 HEAD
提交的状态。
ghee restore README.md
重置
将表中所有文件重置到指定提交的状态。
ghee reset add133b4-f58b-a64e-992a-46f983a0e7ed
依赖项
~9–23MB
~316K SLoC