催化:一种为锡拉和卡桑德拉设计的ORM,用锈迹书写

2022-02-17 09:53:42

以下是Jasper Visser的客座帖子,他是一位自学成才的程序员,也是一位热衷于可伸缩软件设计的Rustacean。Jasper是那种手工自动化一分钟任务的程序员,喜欢开发开源项目并为之做出贡献。

关于生锈的更多信息,ScyllaDB的开发人员正在举办一个实践研讨会,涵盖生锈驱动程序和示例代码。

今天,我很兴奋地宣布了一个我在过去几个月里一直在做的项目。我大部分的工作时间都在使用Java和SQL。在业余时间,我喜欢了解新技术和新语言。我已经编写了很长一段时间了,大约5年前开始使用Swift,这是一种由苹果公司创建的用于制作iOS/macOS应用程序的语言。我喜欢创建用作其他人项目构建块的库。斯威夫特看起来很像Rust,这是一种用于催化反应的语言。

在阅读了一些关于斯威夫特发展的RFC后,我遇到了锈迹。Swift希望实现Rust的功能,尤其是独特的所有权模式。Rust与Swift大约在同一年发布。虽然Swift更符合人体工程学(例如,没有寿命),但Rust提供了更大的灵活性、安全性和速度。我真的很喜欢Rust的所有权体系和社区的努力,让它在保持安全的同时与C的速度竞争。我在Rust中做了一些副项目,包括GRDB-ORM,它是GRDB的一个包装,反过来又是SQLite的一个薄包装。GRDB-ORM生成高速、安全的Swift代码,可以与SQLite数据库交互。它根据数据库的元数据生成Swift结构。我喜欢拥有一个从数据库元数据中派生代码的可靠库的想法。

我最初的目标是构建一个能够在iOS应用程序之间进行通信的服务器。服务器需要一个能够在保持可伸缩性的同时处理大量写操作的数据库。由于水平扩展是关系数据库的一个问题,我必须搜索一个不受扩展限制的非关系数据库。

与GRDB-ORM合作是一种乐趣。生成的代码确保了我不会出现运行时问题。我知道我在服务器端也需要类似的东西。

我遇到了“锡拉布”,我立刻就喜欢上了它的设计:多台计算机(节点)相互对话,交流最新的更新。令我印象深刻的是,ScyllaDB每秒可以处理10亿次插入,并正式支持物化视图,这是Apache Cassandra中非常缺乏的功能。再加上扩展和添加节点一样简单,你就拥有了一个很棒的数据库。

一个很棒的数据库应该会有很棒的驱动程序。我真的很高兴看到车队最近释放了一名官方的铁锈锡拉司机。我认为这个团队用最新的技术开发了一个生锈的驱动程序,尤其是Tokio框架。它是完全异步的,并提供了大量的proc宏,使库符合人体工程学,易于设置。

rust scylla驱动程序的维护人员对问题做出快速响应,并乐于分析和改进驱动程序。这促使我写下了Catalystal,这是一个建立在Scyllab官方Rust驱动程序之上的速度极快、安全的ORM(对象-关系映射)。我这样做是因为我讨厌:

❌ 表和结构之间的映射不正确。你通常想要一个Rust struct,它用锡拉的表格一对一地映射。如果手工创建Rust结构,则可能会在字段声明中输入错误。

库还没有完全完成:还不支持所有类型。请随时添加新类型并提交PR!

ORM专门使用Rust驱动程序的预处理语句缓存。这意味着驱动程序将在可能的情况下重用查询,以尽可能快的速度执行查询。要检查基于此表定义生成的内容,请参阅此文件。Rust结构在指定的目录中生成。这意味着您可以生成一次映射,并在没有运行“锡拉卜”定义的情况下使用您的板条箱。

确保“锡拉布”正在运行。对于本教程,我建议在Docker中运行Scyllab。“锡拉布”提供了一门极好的课程,涵盖了铁锈驱动程序,因此我在本指南中跳过了对驱动程序的介绍。

让我通过一些代码向您展示催化的可能性。完成代码的项目可以在这里找到。在本例中,一个简单的表格在Scyllab中定义:

使用复制创建键空间scylla_映射={

确保可以通过端口9042从本地主机访问数据库。可以使用环境变量SCYLLA_URI更改数据库URL。

让我们把手弄脏,从制作生锈的二元板条箱开始:

创建一个rustfmt。货物旁边的toml文件。toml文件。此文件将格式化生成的代码。铁锈。toml文件应仅包含以下内容:

在您最喜欢的IDE中打开项目并导航到Cargo。toml文件。添加对催化剂和锡拉板条箱的依赖性:

[构建依赖项]

运行可执行文件,它将下载依赖项。这是让自动完成在IDE中工作所必需的(我必须重新启动IDE)。“生成依赖项”部分用于生成。rs文件。构建中的代码。在任何源文件中进行代码更改时,rs将执行。

创建一个构建。在货物旁边有rs文件。汤姆和鲁斯特福特。toml文件。在这个版本中。rs,我们调用表映射器来生成结构。将此代码复制粘贴到新文件中:

使用Catalystic_table_to_struct::transformer::DefaultTransformer;

定制点。DefaultTransformer不是智能的,因此如果您想做更多的工作,可能需要将其更改为用户特定的转换器。有关如何执行此操作的示例,请参阅此文件。

将下面的键值对添加为环境变量。您可以在IDE或终端中执行此操作,如果您从以下位置运行货物:

首先,让我们运行简单的CRUD操作。此处还提供了示例操作。首先,我们需要一个CachingSession,一个围绕常规Scyllab会话的薄包装,用于缓存准备好的语句。

使用Catalystal::env_property_reader::database_url;

现在我们已经生成了可以在这些结构上操作的文件和会话,让我们尝试使用Person结构。在主菜单中添加此方法。rs文件:

///这是一个你可以对一个人做什么的例子

当你现在运行应用程序时,你会在日志中看到它插入了这个人,重新选择了他,更新并删除了数据库中的内容。生成了很多代码,我将引导您完成这些代码。

从数据库元数据派生的文件可能有点难以承受。下图简要概述了生成的内容:

如上图所示,为数据库中的每个表生成了一些结构。箭头显示了可用的转换方法:

如果要插入person,需要PersonRef,如果要更新行,则需要PrimaryKeyRef。

有关如何使用此功能的示例,请参阅此文件。当您想要更新动态列时,应该使用UpdateableColumnRef枚举。

现在我们已经使用预定义的查询生成了结构,您可能需要编写自己的查询。这可以通过宏板条箱实现。这就是你想要调用的方法,你可以在这里找到一个例子。值得注意的是:只支持静态查询。这意味着您不能在运行时构建查询,并在编译时检查它!

让我向您展示如何编写编译时检查查询。首先添加另一个环境变量;这是必要的,以便宏可以找到定义结构的模块:

fn询问年龄大于(

宏将通过选择所有列来替换select*。这是有目的的,因为使用*时,准备好的语句可能会不同步。在上面的示例中,该方法返回SelectMultiple结构。查询宏可以读取所需的查询类型。使用SelectMultiple结构,可以执行以下操作:

下面的代码显示了如何使用SelectMultiple type选择内存中的所有内容:

///演示如何编写编译时检查查询的简单方法

#[tokio::main]

宏在确定查询类型方面非常聪明。它将拒绝已经使用表到结构映射器预定义的查询,因此您永远不会编写已经生成的查询。

我们研究了如何从Scyllab/Cassandra表生成Rust结构。你可以用桌子来搭建板条箱。这个板条箱将确保你的Rust structs始终与数据库同步。

💡 您可以在中添加生成的文件。gitignore文件。它是生成的,并且应该始终生成相同的输出。

为简洁起见,我将不详细介绍Transformer特性,但将其用于:

实现变压器特性并不难;请参阅示例文件以了解如何执行此操作。

使用宏板条箱,可以创建编译时检查的查询。它返回一个带有方法的特定类型。因此,如果您编写一个计算行数的查询,它将返回一个Count结构,您可以在其上调用“Count”。这个额外的步骤确保查询完全按照您的要求进行。

💡 创建一个工作空间,并创建一个单独的库,其中包含生成的实体和编译时检查的查询。这样的话,就可以进行构建了。不是每次更改源文件时都会执行rs。在cql文件中添加一个rerun if changed命令,然后它将在架构更改时自动运行。

另一个非常有用的特性是物化视图和基础视图之间的映射。如果物化视图的列与基础视图完全相同(允许使用不同的主键),则可以通过两种方式将物化视图转换为基础表:

宏板条箱中有一个特殊的查询基表宏。您可以编写自定义查询来查询物化视图。宏的返回类型将是基表的类型。宏将进行一些检查,以查看转换在编译时是否安全。你可以在这里找到一个例子。这表明查询是在物化视图中完成的,但返回类型是基表的结构。

生成的代码还将执行检查,以查看是否可以进行自动转换,并在安全的情况下生成代码。

Catalystic能够做很多事情,使其与锡拉互动非常容易和安全。如果实施,有几件事会很有用:

并非所有类型都受支持。虽然支持基本类型,但它缺乏对UDT的支持。

只要查询是静态的,就可以在编译时检查查询。这意味着您不能有条件地向查询添加条件。我不确定是否有可能取消这一限制。

Catalystal提供了所有功能的示例,以及大量测试。如果你还有问题,就从https://github.com/Jasperav/catalytic/discussions或者看看示例文件夹。

Rust是一种很棒的语言,在我看来,它是最方便的语言。“锡拉布锈迹”驱动程序即使不是最快的,也已经是最快的“锡拉布”驱动程序之一。它还提供了很多安全性。加上Catalystic,Rust developer现在有了一个非常强大的工具集,可以以可能最快的方式在Scyllab上构建。

锡拉布的发展也在飞速发展。2022年锡拉峰会于2月9日至10日举行,使用锡拉的公司举行了会谈。Piotr Sarna的演讲“锡拉司机:一个司机统治他们所有人”特别有趣。你可以按需观看他的会议和所有演讲。