Rust で SQL Compiler を作ってる
sqlc がとても素敵だなと思っており、自社では sqlc (go の pgx/v5) を採用している。ただ sqlc の開発が不安定だったり、TypeScript 版がメンテナンスが止まってしまったり、migrate や formatter が付いていたら ... という気持ちがあったので、いい機会なので作る事にした。
また、最近は Rust の難しい部分を LLM が吸収してしまうことや、Tokio が本当に素晴らしい事もあり Rust でのウェブアプリも現実的なのでは?と考えているため、まずは Rust の tokio-postgres 向けで試してみることにした。うまくいったら Go の pgx/v5 向けも追加する感じで。
製品名
自社は昔 Lua 向けの Linter を作っていたのだが、その名前にあやかって ruri とすることにした。名前大事。ここからは ruri == SQL Compilerと思って読んで欲しい。
Compiler 設計方針
基本的には sqlc と同じく SQL をコンパイルして Rust のコードを生成するだけ。ただ sqlc が頑張れていなかった部分は積極的に対応していく。また複数データベースへの対応はメンテナンスが厳しいため Postgres のみ対応とすることにした。将来的に SQLite や DuckDB といった自社が利用しているデータベースに対応してもいいかもしれないが、正直あまりメリットはないと考えている。
もちろん libpg_query.rs を利用する。Postgres 17 対応。
Migarte 設計方針
sqlc の不満の1つがマイグレーションツールがなかったこと、SQL Compiler にマイグレーションツールが付いていたらなぁ ... ってずっと思っていた。
またマイグレーションも sqldef や pg-schema-diff のように変更差分をうまく吸収して最新の Schema だけ管理すれば良いという仕組みを使いたかったのだが、細かい部分で不安が多かったので、丁寧に対応することにした。ruri migrate コマンドを作る。
pg-chema-diff や sqldef を参考にして実際の Postgres に接続して plan を立てて apply するという仕組みを採用する事にした。独自性を出すメリットはない。
Formatter 設計方針
色々フォーマッターはあるが、個人的に使ってて違和感が少なかった pgFormatter 互換を目指すことにした。難しく考えず ruri fmt で使えるだけ。設定ファイルは用意しない。ただここをミスると死ぬので死ぬほど丁寧に実装する。
Go への対応
基本は Rust の tokio-postgres での利用を想定しているが、Go の pgx/v5 でも利用できるようになっている。
Insta を利用したスナップショットテスト
テストには schema.sql / query.sql を用意して、スナップショットテストをすることで生成される Rust コードを保証する。
スナップショットテスト(承認テストとも呼ばれます)は、 値を基準値(スナップショット)と比較するタイプのテストです。 これはassert_eq!で値を基準値と比較するのと似ていますが、 単純な文字列比較とは異なり、スナップショットテストでは複雑なデータ構造に対しても テストを実施できます。 値を比較し、変更内容を詳細に確認できる包括的なツール群を備えています。SQL Compiler はスナップショットテストとの相性が本当に良い。大量の SQL テストとスナップショットを書いている。
ruri の現状
LLM を使って Gist に 2026 年 2 月時点でのまとめたので興味ある人は見てみてほしい。雰囲気がわかってもらえると思う。

まとめ
結局アプリを作るには RDB (というかトランザクション) が必要なので、SQL はまだまだ利用される。そうであれば使いやすい SQL からのコード生成、SQL マイグレーション、SQL フォーマッターを徹底的なテストにより実現したツールを作るのは今の時点では悪くないと判断した。
SQLite が大量のテストをしているように、ruri も大量のテストをしている。今後もテストは増えていく予定だ。
Go への対応とSQL フォーマッターも一段落しそうなので、次は Playground (つまり Wasm) を使ってブラウザですぐに確認できる仕組みも準備していきたい。
まずは社内で利用して、商用製品として展開できるのが理想だと思っている。