ここ数日のDBIx::Skinny
Wassrでつぶやいてたら取り込まれたり、githubのcollaboratorに入れてもらったのでpushしたりしたことのまとめ。
■$row->setの引数がhashからhashrefに変わった
before
$row->set($key => $val);
元々は単一のkeyでsetするのが基本、ということでhashだったらしいです。とは言え、複数でも問題なく使えてました。で、updateはhashrefを渡すので、それと統一された形です。
after
$row->set({ $key => $val });
CPANに上がってるのとインタフェースが変わってるので、要注意です。
■order_byの拡張
before
MyApp::DB->search($table, $where, { order_by => [ { id => 'desc' } ] });
hashrefをn個入れたarrayrefしか受け付けなかったのを、hashref単体や文字列でもorder_byできるようにしました。
after
MyApp::DB->search($table, $where, { order_by => 'name' }); MyApp::DB->search($table, $where, { order_by => { id => 'desc' } });
■$row->updateした時に自動でsetするように
before
use Test::More qw/no_plan/; my $row = MyApp::DB->single($table, { id => 1 }); is $row->name, 'hoge'; $row->update({ name => 'fuga' }); is $row->name, 'fuga'; # failed, got 'hoge'
DBIx::Skinny::Rowのオブジェクトに対してupdateをかけた場合、DBのデータは更新されますが、$rowが持ってる値は更新されませんでした。なので、このテストは通りませんでした。
これはDBIx::Skinny::Rowが持ってるカラムのキャッシュがupdateでは更新されないためで、
$row->set({ name => 'fuga' }); $row->update; is $row->name, 'fuga' # passed
と書く必要がありました。set呼ぶとキャッシュがクリアされるので、こっちはOK。
カラムのキャッシュと言っても、別にmemcachedとか使ってるわけじゃなくて、単にrowオブジェクトの中に値を持ってるだけです。$row->nameとか呼ぶ度にinflateするのが無駄なので、そこをキャッシュしてくれてるんですね。
とは言え、$row->updateにhashrefを投げた時にもキャッシュクリアして欲しいので、$row->updateした時に内部でsetも呼ぶようにさっき変更しました。なので、前述のテストも最新版だと通ります。
なんでこうなってるかと言うと、元々は
MyApp::DB->update({ name => 'fuga' }, { id => 1 });
って感じでRowオブジェクトを取らずに外からDBにアクセスするのがSkinnyのアプローチだったのかなと推察。