#sqlite #命令行 #嵌入式数据库 #创建 #duck-db #Web 应用 #查询

bin+lib ayb

ayb 使创建、托管和共享嵌入式数据库(如 SQLite 和 DuckDB)变得容易

7 个版本

0.1.7 2024年2月25日
0.1.6 2024年1月14日
0.1.5 2023年11月18日
0.1.4 2023年6月4日
0.1.3 2023年4月28日

#442 in Web 编程

Download history 5/week @ 2024-03-09 2/week @ 2024-03-30 1/week @ 2024-04-06 1/week @ 2024-04-20 3/week @ 2024-05-18 1/week @ 2024-05-25

每月下载量 107

Apache-2.0

130KB
3K SLoC

ayb

ayb 使创建数据库、与协作者共享以及从 Web 应用程序或命令行查询变得容易。

使用 ayb,您的所有(数据)库最终可以归您所有。让 SQL 为正义而战。

Build status

简介

ayb 是一个数据库管理系统,具有易于托管的实例,使用户能够快速注册账户、创建数据库、与协作者共享以及从 Web 应用程序或命令行查询。一个 ayb 服务器允许用户创建 SQLite 数据库(其他数据库即将推出),并通过 HTTP API 公开这些数据库。

要了解更多关于为什么 ayb 重要的信息,如何工作以及适用于谁,请阅读这篇介绍性博客文章

alpha 警告ayb 既不功能完整,也不是生产就绪。功能如身份验证、权限、协作、隔离、高可用性和事务支持在路线图中,但今天不可用。我将 ayb 作为爱好者的副项目进行开发。

入门

安装

ayb 用 Rust 编写,作为 ayb 包提供。假设您已在计算机上安装了 Rust,则安装 ayb 只需一条命令。

cargo install ayb

运行服务器

ayb 服务器将其元数据存储在 SQLitePostgreSQL 中,并将托管在其本地磁盘上的数据库存储。一个 ayb.toml 文件告诉服务器要监听哪些主机/端口上的连接,如何连接到数据库以及托管数据库的数据路径。您可以使用 ayb default_server_config 生成启动文件。

$ ayb default_server_config > ayb.toml

$ cat ayb.toml

host = "0.0.0.0"
port = 5433
database_url = "sqlite://ayb_data/ayb.sqlite"
# Or, for Postgres:
# database_url = "postgresql://postgres_user:test@localhost:5432/test_db"
data_path = "./ayb_data"

[authentication]
# A secret (and unique to your server) key that is used for account registration.
fernet_key = "<UNIQUE_KEY_GENERATED_BY_COMMAND>="
token_expiration_seconds = 3600

[email]
from = "Server Sender <[email protected]>"
reply_to = "Server Reply <[email protected]>"
smtp_host = "localhost"
smtp_port = 465
smtp_username = "[email protected]"
smtp_password = "the_password"

运行服务器只需一条命令

$ ayb server

运行客户端

一旦服务器运行,您可以注册一个用户(在这个例子中,是marcua),创建一个数据库 marcua/test.sqlite,然后像您喜欢的那样发出SQL命令。下面是如何在命令行中这样做

$ ayb client --url http://127.0.0.1:5433 register marcua [email protected]
Check your email to finish registering marcua

# You will receive an email at [email protected] instructing you to type the next command
$ ayb client confirm <TOKEN_FROM_EMAIL>
Successfully authenticated and saved token <API_TOKEN>

$ ayb client create_database marcua/test.sqlite
Successfully created marcua/test.sqlite

$ ayb client list marcua
 Database slug | Type 
---------------+--------
 test.sqlite   | sqlite 

$ ayb client query marcua/test.sqlite "CREATE TABLE favorite_databases(name varchar, score integer);"

Rows: 0

# If you don't pass a query to the query command, ayb launches an interactive query session
$ ayb client query marcua/test.sqlite
Launching an interactive session for marcua/test.sqlite
marcua/test.sqlite> INSERT INTO favorite_databases (name, score) VALUES ("PostgreSQL", 10);

Rows: 0
marcua/test.sqlite> INSERT INTO favorite_databases (name, score) VALUES ("SQLite", 9);

Rows: 0
marcua/test.sqlite> INSERT INTO favorite_databases (name, score) VALUES ("DuckDB", 9);

Rows: 0
marcua/test.sqlite> SELECT * FROM favorite_databases;
 name       | score 
------------+-------
 PostgreSQL | 10 
 SQLite     | 9 
 DuckDB     | 9 

Rows: 3
marcua/test.sqlite>

$ ayb client update_profile marcua --display_name 'Adam Marcus' --links 'http://marcua.net'

Successfully updated profile

$ ayb client profile marcua
 Display name | Description | Organization | Location | Links 
--------------+-------------+--------------+----------+-------------------
 Adam Marcus  |             |              |          | http://marcua.net 

注意,命令行还为您保存了一个配置文件,以便您不必每次都输入服务器URL或API令牌。如果您想明确设置这些,则可以使用命令行标志 --url/--token 和环境变量 AYB_SERVER_URL/AYB_API_TOKEN 来覆盖保存的配置。默认情况下,配置文件可以在此处找到

  • Linux: /home/alice/.config/ayb/ayb.json
  • MacOS(未经测试): /Users/Alice/Library/Application Support/org.ayb.ayb/ayb.json
  • Windows(未经测试): C:\Users\Alice\AppData\Roaming\ayb\ayb\config\ayb.json

上面的命令行调用是对ayb的HTTP API的薄包装。以下是与上面相同的命令,但使用了curl

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/register -H "entity-type: user" -H "entity: marcua" -H "email-address: [email protected]"

{}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/confirm -H "authentication-token: TOKEN_FROM_EMAIL"

{"entity":"marcua","token":"<API_TOKEN>"}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/marcua/test.sqlite/create -H "db-type: sqlite" -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>"

{"entity":"marcua","database":"test.sqlite","database_type":"sqlite"}

$ curl -w "\n" -X PATCH http://127.0.0.1:5433/v1/entity/marcua -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>" -d "{\"display_name\": \"Adam Marcus\"}"

{}

$ curl -w "\n" -X GET https://127.0.0.1:5433/v1/entity/marcua -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>"

{"slug":"marcua","databases":[{"slug":"test.sqlite","database_type":"sqlite"}],"profile":{"display_name":"Adam Marcus"}}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/marcua/test.sqlite/query -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>" -d 'CREATE TABLE favorite_databases(name varchar, score integer);'

{"fields":[],"rows":[]}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/marcua/test.sqlite/query -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>" -d "INSERT INTO favorite_databases (name, score) VALUES (\"PostgreSQL\", 10);"

{"fields":[],"rows":[]}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/marcua/test.sqlite/query -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>" -d "INSERT INTO favorite_databases (name, score) VALUES (\"SQLite\", 9);"

{"fields":[],"rows":[]}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/marcua/test.sqlite/query -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>" -d "INSERT INTO favorite_databases (name, score) VALUES (\"DuckDB\", 9);"

{"fields":[],"rows":[]}

$ curl -w "\n" -X POST http://127.0.0.1:5433/v1/marcua/test.sqlite/query -H "authorization: Bearer <API_TOKEN_FROM_PREVIOUS_COMMAND>" -d "SELECT * FROM favorite_databases;"

{"fields":["name","score"],"rows":[["PostgreSQL","10"],["SQLite","9"],["DuckDB","9"]]}

隔离

ayb允许多个用户在同一台机器上存储的数据库上运行查询。隔离功能可以防止一个用户访问另一个用户的数据,并允许您限制任何单个用户能够使用的资源。

默认情况下,ayb使用SQLITE_DBCONFIG_DEFENSIVE标志,并将SQLITE_LIMIT_ATTACHED设置为0,以防止用户损坏数据库或连接到文件系统上的其他数据库。

为了进一步增强隔离,ayb使用nsjail来隔离每个查询的文件系统访问和资源。当启用此形式的隔离时,ayb将启动一个新的由nsjail管理的进程来执行针对数据库的查询。我们尚未对该方法的性能开销进行基准测试。

要启用隔离,您必须首先构建nsjail,您可以通过scripts/build_nsjail.sh来完成。请注意,nsjail依赖于一些其他软件包。如果您在构建时遇到问题,查看其Dockerfile可能会有所帮助,以了解那些需求。

一旦您有了nsjail二进制文件的路径,请将以下内容添加到您的ayb.toml

[isolation]
nsjail_path = "path/to/nsjail"

测试

ayb主要通过对尽可能真实的环境进行端到端测试来测试,单个模块也可能提供更具体的单元测试。要运行测试,请输入

cargo test --verbose

因为测试涵盖了隔离,运行端到端测试需要nsjail二进制文件。要构建并将nsjail放置在适当的目录中,请运行

scripts/build_nsjail.sh && mv nsjail tests/

常见问题解答

ayb是为谁准备的?

介绍性博客文章中有一个部分描述了每个可以从ayb的旨在简化数据库创建、交互和分享的目标中受益的群体。学生将从遇到更少的操作障碍来编写他们的第一个SQL查询或与导师或教师分享他们正在进行的数据库以获得帮助中受益。分享者,如科学家和记者,将从轻松发布数据集并与合作者分享中受益。最后,任何关心其数据主权的人都将从在一个可以轻松启动数据库的世界中受益,这样更多的数据可以生活在他们控制的数据库中。

名字是怎么回事?

感谢您提问。我希望这个答案能唤起一些怀旧之情!感谢Meelap Shah和Eugene Wu说服我不把这个项目叫做stacks,感谢Andrew Lange-Abramowitz将其与著名的水印联系起来,以及感谢Meredith Blumenstock倾听我对这一切的烦恼。

路线图

以下是项目的粗略路线图,列表顶部的事项更有可能首先完成。优先级列表的详细信息可以在这个项目板上找到,其中最有可能完成的事项位于待办事项列表的顶部。

  • 使单用户ayb体验出色
    • 减少对PostgreSQL(SQLite元数据存储)的依赖。鉴于ayb的目标是简化数据库的创建、分享和查询,但运行ayb需要您支付非微不足道的操作成本,这令人沮丧。虽然Postgres最终将有助于在多个ayb节点之间进行协调,但单节点版本应该能够在SQLite中存储其元数据,而无需大量设置成本。
    • 身份验证和权限。添加身份验证/登录功能,并添加端点权限,以便您不能随意对任何数据库发出查询。
    • 隔离。由于一个ayb实例可以有多个租户/数据库,我们希望使用许多容器/隔离/微虚拟化项目之一来确保一个租户不能访问另一个租户的数据。
    • 集群。支持多个ayb节点来服务数据库和请求。虽然单个数据库不会跨越多台机器,但并行/分布式将发生在用户和数据库之间。
    • 节点之外的持久性。使用像LiteFS这样的项目,将数据库更新流式传输到持久存储,并在ayb节点消失时允许故障转移。
    • 会话/事务。ayb的查询API是一个无状态的请求/响应API,这使得无法启动数据库事务或在会话中发出多个查询。在API中公开会话将允许会话中有多条语句,进而扩展到事务。
    • 数据库的导入/导出。ayb已经使用现有的良好建立的文件格式(例如,SQLite)。应该有端点可以以这些格式将现有数据库导入到ayb中,或者导出底层文件,以便您不会被锁定。
  • ayb扩展到更多人和社会软件
    • 协作。除了易于创建和查询数据库外,还应该易于与他人共享数据库。两个用例包括添加私有协作者和允许公共只读访问。
    • 分支。允许用户分支自己的数据库副本将使协作者能够混合和构建彼此的工作。
    • 版本控制。为了使执行敏感操作不那么可怕,以及使科学家能够引用和发布他们工作的检查点,用户应该能够快照并回滚到某个时间点的数据库。
    • DuckDB。除了SQLite数据库外,还允许用户创建DuckDB数据库,这将使您只需一条命令即可创建数据仓库。这项工作依赖于DuckDB项目。首先,DuckDB文件格式正在快速变化,以适应项目的1.0版本发布。此外,我不知道有与LiteFS对DuckDB中处理节点之外的持久性等效的流式复制项目。
    • PostgreSQL线协议。虽然HTTP API使得构建新的Web应用变得简单,但通过PostgreSQL线协议公开ayb将允许现有工具和库连接并查询ayb数据库。
  • 使用Web前端提高可发现性
    • 提供与命令行界面类似的Web界面。就像GitHub/Gitea/Forgejo使git更容易接触一样,您不需要为创建、共享和查询ayb数据库支付命令行知识税。
    • 探索人们的公共数据集。除了简化命令行之外,像GitHub这样的平台也使人们更容易找到用户的公开共享仓库,跟踪他们的工作,并复制一份供您自己探索。同样的体验也应该适用于ayb托管数据库。

贡献

(本节受LiteFS项目的启发,并且只是该项目众多优点之一。)

ayb贡献的工作方式与大多数GitHub项目略有不同

  • 如果您有一个小的错误修复或打字错误,请直接将PR提交到此存储库。
  • 如果您想贡献文档,请直接将PR提交到此存储库。
  • 如果您想贡献一个功能,请首先在此GitHub存储库的问题中创建并讨论该功能。一旦在问题中以及可能的设计文档中讨论并确定了功能和一些更细致的细节,提交一个pull request。我可能会礼貌地拒绝未经讨论/设计的pull requests。

此项目有一个路线图,并且功能是按照一定顺序添加和测试的。我在要求在提交pull request之前先讨论/设计功能时添加了一些摩擦,以确保我可以专注于动机明确、顺序合理且易于理解的函数。

依赖项

~53–87MB
~1.5M SLoC