この記事は ラクス Advent Calendar 2021 24日目の記事です。
php-mysql-engineとは
php-mysql-engineは、Psalmでも知られるVimeo社が公開したライブラリで、PDOを使ったMySQLの操作をデータベースサーバに接続することなくエミュレートしてくれるというものです。
これを使えばDBを含めた自動テストを手軽に実行できるということで、Vimeo社はもちろん、日本だとpixivの一部サービスでも利用しているそうです。
PHPerKaigi 2021のLTでも紹介されていましたね。
ところで
話は変わりますが、ログなどの集計にSQLを使いたいことが稀によくありませんか?私はあります。
数ヶ月に一回しか使わないawkよりも、普段よく使うSQLでデータ集計したいところです。
ということで、php-mysql-engineを使ってCSVデータを集計できるツール、csv-queryを作成しました!
記事公開時点 (2021/12/24) ではまだ正常系が最低限動くというレベルですが、一応上記のようなログ集計にも使えるかと思います。
csv-query
インストール
上記リポジトリをcloneし、composer install --no-devします。
bin/ディレクトリの中にcsv-queryコマンドがあります。
使い方
csv-queryは標準入力のデータをstdinという名前のテーブルに格納します。コマンドの第一引数にSQLを指定します。
デフォルトでは一行目をヘッダ行とみなし、その内容をカラム名に利用します。
$ cat data.csv
id,name
1,John
2,Alice
3,Dave
4,Bob
$ cat data.csv | csv-query 'SELECT * FROM stdin WHERE id < 4 ORDER BY name'
id,name
2,Alice
3,Dave
1,John
オプションによってヘッダ行を無効にしたり、タブ区切りのようなファイルを読み込むことも可能です。詳細はREADMEに譲ります。
システム要件
PHP>=8.0, PDO_mysqlが必要です
所感
php-mysql-engineについて
- 実際のPDOとは細かい差異がある
- 先述のpixivさんのブログでもあるように、普通のPDOを使っていれば問題ない場面でも
php-mysql-engineの制限(またはバグ?)によって動かない場面がありました。- CREATE TABLE文に
COLLATEかCHARACTER SETが必要 - DSNの
mysql:hostname=localhost;dbname=csv_query;の末尾セミコロンを取るとエラーになる
- CREATE TABLE文に
- 先述のpixivさんのブログでもあるように、普通のPDOを使っていれば問題ない場面でも
- まだサポートされていないメソッドもある
-
PDOStatement::getColumnMeta()を利用しようとしたところ、未サポートのようでPDO object is uninitializedというFatal Errorが発生しました。
-
CLIツールの作成
- READMEを先に書くとやりやすい
- 個人開発ということで、設計書を書いたりはしていませんが、READMEにある程度仕様をまとめたおかげで確認しながら開発を進められました。
まとめ
通常テスト用ツールとして用いられるphp-mysql-engineの少し変わった使い方を紹介しました。
SQLの文法は基本的にMySQL準拠なので、普段MySQLで開発している方には特に使いやすいのではないでしょうか。
ちなみに弊社が業務で使っているのはPostgreSQLなので、私自身文法など若干馴染めていません。
(誰かphp-pgsql-engine作ってくれないかな……)