Java/GradleでANTLRを使い、DDLからテーブル定義書を作成、その1
ゴール:DDL文からテーブル定義書を自動生成
さて、今回ANTLRを使おうと思ったのは、SQLのDDL文からテーブル定義書を自動作成したいからだ。
例えば、こんなDDLがあるとする(MYSQL)。
/* 書籍テーブル */
create table tbl_book (
/* 本のID */
bk_id bigint auto_increment primary key
/* 書籍名称 */
,bk_name text not null
/* 著者名称 */
,bk_author varchar(256) not null
);
あるいはこうだ。
/* 2019/10/1:256では足りないので1024に変更 */
alter table tbl_book modify bk_author varchar(1024) not null;
これらのDDLを読み込んでテーブル定義書を自動生成したいという要求だ。
- 書籍テーブル
- 本のID:bk_id、プライマリキー、自動連番
- 書籍名称:bk_name、text型 not null
- 著者名称:bk_author、varchar(1024) not null、2019/10/1:256では足りないので1024に変更。
既存ライブラリの利用
もちろん、SQLを解析するJavaライブラリもあるようだが、insertやselectの処理は一切必要無い。create tableとalter tableのみ処理できればよい。しかも、それらのライブラリとは着目点が全く異なる。ここでは、「コメントを拾えること」が重要になるわけだ。
さらに、ANTLR用のMYSQL構文定義もある。これはMySQL Workbenchのコードの一部だ。
こんな大それたものは必要無い、やりたいことは非常に単純なことなので。
しかし、とりあえず、この定義からパーサーを作ってみることにする。
MySQL Workbenchの定義からパーサーを作成してみる
結論から言えば、これはうまく行かなかった。というのも、MySQL WorkbenchはC++製であり、C++で記述された他のファイルが必要になるからだ。以下では無理やりJavaコードを生成しているが、当然クラスが足らないのでコンパイルできない。
ともあれ、以下の手順になる。
ここから、以下のファイルを取り出して、prsフォルダに入れる。
- MySQLLexer.g4
- MySQLParser.g4
- predefined.tokens
build-parsers.cmdにあるように、以下のコマンドで生成するようなので、これをアレンジしてみる。
java -Xmx1024m -jar %WB_3DPARTY_PATH%\bin\antlr-4.7.1-complete.jar -Dlanguage=Cpp -listener -visitor -o ../mysql -package parsers MySQLLexer.g4 MySQLParser.g4
このantlr-4.7.1-complete.jarというのは、antlr本体jarに外部ライブラリを組み合わせて一つのjarにしたものにすぎないようだ。したがって、Gradleでも実行できる。
実は、gradleのantlrプラグインで上記と同じパラメータを指定する方法が不明なため、antlrプラグインを使うのはやめた。直接antlrのmainを呼び出すことにする(他のgradleプラグインについてもそうなのだが、マニュアルが不可解でさっぱり理解できない)。
build.gradleを以下にする。
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
jcenter()
}
sourceSets {
main {
java.srcDirs = ['src', 'src2']
}
}
task genParser(type:JavaExec) {
main = 'org.antlr.v4.Tool'
classpath = sourceSets.main.output + configurations.compileClasspath
args '-Dlanguage=Java', '-listener', '-visitor',
'-o', 'src2/com/gwtcenter/parsers',
'-lib', 'prs',
'-package', 'com.gwtcenter.parsers',
'prs/MySQLLexer.g4', 'prs/MySQLParser.g4'
}
dependencies {
implementation "org.antlr:antlr4:4.7.2"
}
あとは、gradleでgenParserを実行すれば、以下の状態になる。ファイルが不足しているのでエラーが出ている。
Positive Technologies MySQL grammarからパーサーを作成してみる
もうひとつあった。これを作成してみる。
以下のファイルを取り出し、prsフォルダに入れる。
- MySqlLexer.g4
- MySqlParser.g4
build.gradleを次に変更
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
jcenter()
}
sourceSets {
main {
java.srcDirs = ['src', 'src2']
}
}
task genParser(type:JavaExec) {
main = 'org.antlr.v4.Tool'
classpath = sourceSets.main.output + configurations.compileClasspath
args '-Dlanguage=Java', '-listener', '-visitor',
'-o', 'src2/mysqlparser',
'-package', 'mysqlparser',
'prs/MySqlLexer.g4', 'prs/MySqlParser.g4'
}
dependencies {
implementation "org.antlr:antlr4:4.7.2"
}
gradleでgenParserを実行すると、以下になる。
エラーは出ていない。次回はこれを使って目的が達成できるか検証してみる。