RoomのスキーマjsonからmermaidのER図を出力するGradle Pluginを作った
December 28, 2024
Roomにはスキーマのjsonファイルを出力する機能があるが、これを利用してテーブルのリレーションのER図をmermaidで生成するGradle Pluginを作った。
https://github.com/ntsk/room-schema-docs-gradle-plugin
mermaidのER図が記述されたmarkdownファイルを出力するのだが、GitHubではmermaid syntaxをプレビュー表示できる。 これにより本プラグインを利用して出力したファイルをgit管理しておくことで、チーム内でバージョン毎のテーブル構造の変遷を共有することができる。
モチベーション
作ろうと思った経緯として、自身が所属する開発チームがスケールするにつれて全ての開発差分をそれぞれのメンバーが把握することが困難となってきたことがあった。
開発しているプロダクトでは、オフライン対応のためにほぼ全てのレスポンスキャッシュをRoomで保持するようになっており、 並行して様々な機能を開発する中でテーブル構造も次々と変化していく。
ドキュメントを充実させるにしてもコストがかかる上、結局メンテされないドキュメントが残るケースが多かったことから、自動生成したかった。
使い方
README.md
に記載の通りだが、プラグインを追加し、
plugins {
id("jp.ntsk.room-schema-docs") version "1.0.0"
}
jsonファイルを出力しているディレクトリをschemaDir
で、ER図を出力するディレクトリをoutputDir
で指定する。
roomSchemaDocs {
schemaDir = "$projectDir/schemas"
outputDir = "$projectDir/schemas-docs"
}
ここまで設定したら、gradleタスクを実行すると各種スキーマのjsonファイルに応じたmarkdownファイルが生成される。
./gradlew generateRoomSchemaDocs
例えば、sample/schemas のようなjsonファイルから sample/schemas-docs のようなER図が記述されたmarkdownファイルを生成できる。
実装
mermaidには erDiagram
を利用することでER図を記述できる syntax がある。
https://mermaid.js.org/syntax/entityRelationshipDiagram.html
下記のような記号で1対1、1対(0 or 1)、1対多、1対(0 or 多)の関係性を記述することで、 ER図を描画できる。
Value (left) | Value (right) | Meaning |
---|---|---|
o |
o |
Zero or one |
| |
| |
Exactly one |
}o |
o{ |
Zero or more (no upper limit) |
}| |
|{ |
One or more (no upper limit) |
erDiagram
CUSTOMER ||--o{ ORDER : places
CUSTOMER {
string name
string custNumber
string sector
}
ORDER ||--|{ LINE-ITEM : contains
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
本プラグインでは、Kotlin SerializationでRoomが出力したjsonをparseし、このerDiagram syntaxで出力する。
このとき、Roomが出力するjsonのデータ構造をER図にすると下記の通りとなる。
ER図の描画に必要な情報としては下記の通り。
- テーブル名
- カラム名・型
- リレーション情報
テーブル名は、Entity.tableName
から取得。
カラム名は、Entity.fields.columnName
、型は Entity.fields.affinity
から取得できる。
リレーションは、Entity.foreignKeys.table
からリレーション先を特定し、Index.unique
からUNIQUE INDEXの有無やField.notNull
からNOT NULL制約があるかをチェックすることで、1対1、1対(0 or 1)、1対多を判定してerDiagramのsyntaxを割り当てて書き出している。
今後
INDEXが張られているか、ON DELETE設定がどうなってるかも可視化できると便利そうなので、optionで追加したい。