2Way SQLパーサとしてのMirage, Doma, Clione-SQLの比較

前回のエントリに対して,こんな反応がありましたので,「なるほど!」と思い試してみたよ(最近,こればっかw


あと,こちらも。→ 2 Way SQLパーサとしてのDoma - taediumの日記


候補に挙げたのは,Seasar系2Way SQLとしてMirageDoma,あと独自2Way SQLClione-SQLの3つ。それぞれ,もともとSQLパーサ単独で使われることを前提としていないので,それなりに無理をして試させて頂きました。


試したコード一式はこちらにおいておきます。
GitHub - masanobuimai/2way-sql-parser


最低限必要とするライブラリ
Mirage以外は自分自身のJarファイル1つだけでOK。サイズやらなんやらは以下の通り。


Mirage, Clione-SQLと比べるとDomaのサイズが際立ちますが,Doma本来の用途を考えれば,別に普通かなと。


2Way SQLパーサとしての使い方
実現したいのは「2Way SQL文を元に,実行可能なプリペア句付きのSQL文を生成すること」なので,なるべく出来合いのものを利用するようにしている。
元にした2Way SQL文はこんなやつ。

SELECT * FROM BOOK
WHERE AUTHOR = /*author*/'Naoki Takezoe'
ORDER BY BOOK_ID ASC


まずはMirage(ここに載っける実コードは部分抽出なので,まあニュアンスの確認程度で見てちょうだい。

SqlParser sqlParser = new SqlParserImpl(load("01-parameter.sql"));
Node node = sqlParser.parse();
SqlContext ctx = new SqlContextImpl();
ctx.addArg("author", "AUTHOR", "AUTHOR".getClass());
node.accept(ctx);

assertThat(join(ctx.getSql()), is("SELECT * FROM BOOK WHERE AUTHOR = ? ORDER BY BOOK_ID ASC"));
assertThat((String) ctx.getBindVariables()[0], is("AUTHOR"))


パーサも,それからSQLを組み立てるコンテキストオブジェクトもMirage出来合いのものを利用。割といい感じ。


つづいてClione-SQL.

SQLNode node = new SQLParser("").parse(load("01-parameter.sql"));
SQLGenerator gen = new SQLGenerator();
String sql = gen.genSql(params("author", "AUTHOR"), node);
assertThat(join(sql), is("SELECT * FROM BOOK  WHERE AUTHOR = ?  ORDER BY BOOK_ID ASC"));
assertThat(gen.params.get(0), is((Object) "AUTHOR"));


こちらも,パーサというかSQL生成器(SQLGenerator)そのものをちゃっかり拝借。SQLGenerator.genSQL()の第一引数にパラメタ情報を含めたMapを与えるのだけれど,いろいろ面倒だったのでClione-SQLのSQLManagerが持っているstaticメソッド(params())を流用した。


最後にDoma...。なんですが,Domaの場合,出来合いのSQL生成器(NodePreparedSqlBuilder)を流用するのが大変しんどくて,その路線は断念。となると自前でSQL生成器(というかパーサに渡すVisitor)を作らないといけない。
...ってことが分かっただけで良しとしました。

(追記)Domaの作者である id:taedium さんからDomaのサンプルを作ってもらいました。ありがとうございます。
Domaの内部的なSQLパーサをラップして扱いやすくしました by nakamura-to · Pull Request #1 · masanobuimai/2way-sql-parser · GitHub


結論
当たり前と言えばそうかもしんないけど,この手のライブラリは2Way SQLパーサだけとして利用可能なんだなーと(作者がそうゆう利用を望んだかどうかは別ですが。


2Way SQLの記法としては,インデントに意味を持たせていろんな工夫をしているClione-SQLに好感を持ちました。ただ知名度=パーサの成熟度としてみると,MirageDomaに安心感はあるなと。
#それはそうと,Clione-SQLの作者さんって,どなたなんでしょね。


この手の機能(2Way SQLパーサ)を自前で組める腕があれば良いのだけれど...。車輪の再発明もいい加減にしないとと思いつつも,個人的にはどうやって実装してるのか興味はあるので,ヒマ見て内部解析したいなと。
個人的にはJPA(JPQL)とかどーでもいいから,2Way SQLをJSRとかで標準化して欲しい位なんですけどね。:-)