All Articles

Go用のQuery Builder書いた

GoでDatabase操作する時にやっぱり毎回Scanするのつらいし、そもそも生のSQLをガガガっと書くのもちょっと面倒、でもORM使うまでもないくらいという微妙な匙加減のプロジェクトで使えるように作った。

ysugimoto/gqb - Query Builder for Golang

これは何

Go用のQueryBuilderです。メソッドチェーンで条件を繋いで言って最後にGetで一括取得…という感じで、 INSERT / UPDATE / DELETEも対応。細かい関数系も独自に指定できるようにしてあるので自由度はそこそこあると思っている。

結果セットも内部構造体にゴニョゴニョとマッピングしているので、 rows.Scan(&id, &name, …) みたいなことはしなくて良くて、かつ結果セットをそのまま json.Marshal()でJSONにできるのでちょっとしたDB使うAPIのレスポンス用途にちょうどいいかも。 defer rows.Close() 忘れの心配もない安心構造です。その分ちょっとメモリ使っている(repositoryの最後にベンチマーク載せています)

詳しい使い方はREADMEやexamplesを見て頂けると。

database/sql

組み込みパッケージの database/sql パッケージはドライバを上手く隠蔽してて、そのおかげで外のライブラリからからどのドライバで接続しているかがわからなくなっていてちょっと困った(利用者は当然ドライバをimportするから知っているけど、ライブラリは *sql.DB から取得するのはちょっと強引な方法が必要になる。

なのでgqbはユーザに使うドライバを明示してもらう方式にした。結局生のSQLを書くときもドライバ毎の方言は気にしないといけないけど、gqbはそのへんを気にせずに一般的なクエリは同じシンタックスで書けるようにしているので書き味はドライバに左右されない。データベース毎の特殊なカラムタイプとかMySQL固有のアレコレとかは気にしないといけないかもしれないけど…。

ドライバは MySQL / PostgreSQL / SQLite3 の基本的な構文には対応しているけど、それほどデータベースに造形が深くないので足りてないかもしれない。このへんで差分を吸収しているので他にもあったら是非教えてください。

もともと今のプロジェクト用に書いていたものを汎用化した感じなので自身は気に入っている、というかそれほど複雑なクエリを発行することはなくて、長いものはちゃんと書いて素の *sql.DB を介して実行したほうがかえって良かったりするので適材適所という感じ。先に書いた通りCRUD系のAPIと合わせて使うとシンプルになって良いと思う。

エスケープや実行は database/sql に任せてあって自身はクエリを組み立てるだけの役割なのでそれほど気を使っていない。

まとめ

メソッドとシンタックスは某言語のフレームワークに似せていて、分かる人にはわかるかもしれない。クエリの組み立てでマズイ点などあったらPR頂けると嬉しいです。

現場からは以上です。