从 Corda 状态模式生成 Liquibase 更改日志

Generating Liquibase change logs from Corda state schemas

在 Corda 中,我们为可查询状态创建状态模式;例如:

object MyStateSchema {

    object MyStateSchemaV1 : MappedSchema(
        schemaFamily = MyStateSchema.javaClass,
        version = 1,
        mappedTypes = listOf(MyStateEntity::class.java)
    )

    @Entity
    @Table(name = "my_states")
    class MyStateEntity(
        @Column(name = "linear_id", nullable = false)
        val linearId: UUID = UUID.randomUUID(),

        @Column(name = "external_id", nullable = true)
        val externalId: String? = null,

        @Column(name = "identity", nullable = false)
        val identity: AbstractParty = NULL_PARTY,

        @Column(name = "value", nullable = false)
        val value: String = ""
    ) : PersistentState()
}

值得注意的是,MyStateEntity 带有 JPA 注释。由此我们需要生成 数据库不可知 脚本来创建和更新数据库模式;例如:

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
    <changeSet author="Me" id="create-my_states">
        <createTable tableName="my_states">
            <column name="output_index" type="INT">
                <constraints nullable="false"/>
            </column>
            <column name="transaction_id" type="NVARCHAR(64)">
                <constraints nullable="false"/>
            </column>
            <column name="linear_id" type="uuid">
                <constraints nullable="false"/>
            </column>
            <column name="external_id" type="NVARCHAR(255)" />
            <column name="identity" type="NVARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="value" type="NVARCHAR(255)">
                <constraints nullable="false"/>
            </column>
        </createTable>
        <addPrimaryKey columnNames="output_index, transaction_id"
                       constraintName="PK_my_states"
                       tableName="my_states"/>
    </changeSet>
</databaseChangeLog>

目前都是手写变更日志,比较累。我相信一定有更好的方法。我尝试向 gradle 添加一些依赖项,以便我可以 运行 以下命令(遗憾的是它不起作用):

./gradlew generateChangeLog

liquibase 可以自动生成这些脚本吗?

对于全新的数据库(即首次部署节点),我认为手动生成是最好的方法,因为这些 xml 文件用于在节点部署期间创建表。此外,模式是与您的特定 CorDapp 相关的自定义模式。所以我认为自动化意味着需要能够读取 CorDapp 合约文件夹中的模式文件。然而,我们还没有这样的工具。

我也看到一些帖子讨论如果你有一个现有的数据库并且想要自动生成这些 xml 文件,我认为这是当你配置一个 liquidbase.properties 文件并使用 generateChangeLog命令。

就像你说的,手写很累

但是,如果您在开发时以 devMode 启动节点,hibernate 将为您生成架构:

java -jar corda.jar --allow-hibernate-to-manage-app-schema

然后您可以下载 liquibase 发行版并让 liquibase 自动为您生成架构脚本:

./liquibase --driver=org.h2.Driver --changeLogFile=schema.xml --url=jdbc:h2:~/Projects/my-corda-app/build/nodes/ClientName/persistence --username=sa --includeObjects=table:CUSTOM_STATE,table:SECOND_STATE generateChangeLog

这并不完美,因为它几乎肯定不会有正确的作者和 ID,但是,它可以让您从头开始编写。

我用 Corda 打开了一个问题,试图让他们自动完成。

https://github.com/corda/corda/issues/6813