65.9K
CodeProject 正在变化。 阅读更多。
Home

用 Rust 编写的 Git 查询语言

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2023年7月28日

CPOL

3分钟阅读

viewsIcon

5123

介绍 GQL(一种 Git 查询语言),用于对 .git 文件执行类似 SQL 的查询

引言

上个月,我对 Rust 编程语言产生了兴趣,并希望了解更多关于它的信息。所以我开始学习基础知识,并查看用 Rust 编写的开源项目。我还为 Rust 分析器项目创建了一个 PR;它并不依赖于我对 Rust 的了解,而是依赖于我对编译器和静态分析的总体了解。像往常一样,我喜欢通过创建我感兴趣的想法的新项目来学习新事物。

想法

我开始思考一些我喜欢使用的想法,例如更快的搜索 CLI 或一些实用程序应用程序。但后来,我有了个很酷的新想法。

在阅读《构建 Git》(一本关于从头开始构建 Git 的书)时,我了解了 .git 文件夹中每个文件的作用,以及 Git 如何存储提交、分支和其他数据以及如何管理自己的数据库。那么,如果我们有一种在此类文件上运行的查询语言呢?

Git 查询语言 (GQL)

我决定实现这种查询语言,并将其命名为 GQL。我很兴奋地开始这个项目,因为这是我第一次实现查询语言。我决定从头开始实现它,而不是将 .git 文件转换为 SQLite 数据库并运行普通的 SQL 查询。我认为如果将来我可以将 GQL 引擎用作 Git 客户端或分析器的一部分,那就很酷了。

GQL 的实现

目标是将其实现分为两部分。第一部分是将 GQL 查询转换为节点的 AST,然后将其传递给引擎进行遍历并作为解释器执行,或者将来将其转换为 GQL 字节码指令的虚拟匹配。

引擎具有使用 Rust 绑定 git2 库处理 .git 文件的功能,因此它可以执行选择、更新和删除任务,并将选定的数据存储到数据结构中,以便我们可以执行过滤或排序。

为了简化此实现,我创建了一个名为 GQLObject 的结构体,它可以表示此引擎中的提交、分支、标签或任何其他对象,并使其易于使用处理此类型的单个函数执行排序、搜索和过滤。

pub struct GQLObject {
  pub attributes: HashMap<String, String>,
}

GQLObject 只是一个键值为字符串的映射,因此它可以通用地放置任何类型的 info。现在,诸如比较、过滤或排序之类的功能可以轻松地在这些字符串映射上实现。

当前状态

现在可以使用许多 SQL 功能,例如聚合、group byorder bywherehaving 语句、limitoffset 等。

SELECT name, count(name) AS commit_num FROM commits _
             GROUP BY name ORDER BY commit_num DES LIMIT 10
SELECT commit_count FROM branches WHERE commit_count BETWEEN 0 .. 10

SELECT * FROM refs WHERE type = "branch"
SELECT * FROM refs WHERE ORDER BY type

SELECT * FROM commits
SELECT name, email FROM commits
SELECT name, email FROM commits ORDER BY name DES
SELECT name, email FROM commits WHERE name contains "gmail" ORDER BY name
SELECT * FROM commits WHERE name.lower = "amrdeveloper"
SELECT name FROM commits GROUP By name
SELECT name FROM commits GROUP By name having name = "AmrDeveloper"

SELECT * FROM branches
SELECT * FROM branches WHERE ishead = "true"
SELECT * FROM branches WHERE name ends_with "master"
SELECT * FROM branches WHERE name contains "origin"

SELECT * FROM tags
SELECT * FROM tags OFFSET 1 LIMIT 1

例如,选择前 n 个贡献者的姓名和提交次数。

SELECT name, count(name) AS commit_num FROM commits _
             GROUP BY name ORDER BY commit_num DES LIMIT 10

下一步

现在,下一步是优化代码并开始支持更多功能,例如,设计用于删除除 master 分支之外的所有分支的查询。

delete * from branches where name ! "master"

此外,我们可以将项目拆分为小型库,以便我们可以通过多种方式使用它,例如将其集成到 Git 客户端或 IDE 中。

GQL 项目是一个免费的开源项目,因此非常欢迎大家贡献、建议功能或报告错误。

安装或构建

您可以在项目网站上找到有关如何使用二进制文件或 Cargo 安装它或从源代码构建它的完整指南。

Githubhttps://github.com/AmrDeveloper/GQL

期待您的意见和反馈。

您可以在 GitHub 上找到我。

希望您喜欢我的文章。编程愉快!

© . All rights reserved.