DBIのconnectのCallbacksなどでSQLを実行している時とかに、実際にSQLが流れているのかチェックしたい時がある。そういう時どうするのがベスト・プラクティスなのかわからないのだけど、DBIx::QueryLogを使ったら一応できたのでメモ。
テストしたい状況
package My::DBI; use strict; use warnings; use DBI; sub connect { my ($dsn, $username, $password) = @_; my $dbh = DBI->connect($dsn, $username, $password, { Callbacks => { connected => sub { my $dbh = shift; $dbh->do("SET NAMES utf8") or warn $dbh->errstr; return; } } }); } 1;
これのSET NAMES utf8がconnectした時にちゃんと流れているかテストしたい。実際はもうちょっと複雑なときにテストしたい。
DBIx::QueryLogを使ってテストする
DBIx::QueryLogにはloggerを設定できる機能があるので、これを使って文字列にSQLを格納しておくことでテストする。
まず、Logger。
package My::SQL::Logger; use strict; use warnings; sub new { my $class = shift; return bless { sqls => '', }, $class; } sub log { my ($self, %args) = @_; $self->{sqls} .= $args{params}->{sql}; } 1;
これを使ってDBIx::QueryLogでログを取って、テストする。
use strict; use warnings; use Test::More; use DBIx::QueryLog (); my $logger = My::SQL::Logger->new; DBIx::QueryLog->logger($logger); my $guard = DBIx::QueryLog->guard; My::DBI->connect('dbi:mysql:dbname=sample;host=localhost', 'user', 'pass'); like $logger->{sqls}, qr{SET NAMES utf8};