■2010-03-03
* [Perl] DBIx::SkinnyをDBIx::Classな感じで使う
DBIx::Classに慣れた人がDBIx::Skinnyを気軽に使えるように、DBIx::Class::Resultsetっぽいインターフェースをつけてみようと思い:
my $rs = $skinny->resultset_dbictic( 'foo', { 'id' => 1 }, { 'select' => [ 'hoge', 'huga' ], 'order_by' => 'id DESC', } ); # group_by, havingなども
ページングもつけようかな:
my $rs = $skinny->resultset_dbictic( 'foo', undef, { 'page' => 1, rows => 10, 'order_by' => 'id DESC', } ); my $itr = $rs->retireve; my $pager = $itr->pager; # 内部でcount用のステートを発行する。必要ならcount_subrefを渡す # (カウント用SQLと結果用カラムを返すサブルーチンリファレンス)。
いっそスキーマでリレーション定義してjoinできるように:
package Your::Model::Schema; use DBIx::Skinny::Schema; use DBIx::Skinny::DBICTic::Schema; install_table 'user' => schema { pk 'id'; columns qw(id name); has_many 'books' => 'user_book' => 'user.id = user_book.user_id'; }; install_table 'user_book' => schema { # ... }; # package main; my $rs = $skinny->resultset_dbictic( 'user', { 'user.id' => 1 }, { 'join' => [ 'books' ], '+select' => [ qw( books.name ) ], '+as' => [ qw( book_name ) ], } ); # prefetch相当の機能は無し
DBIx::Class使えよ、という本末転倒なわけですが、せっかくなのでhttp://github.com/makamaka/p5-dbix-skinny-dbicticに。
■2010-03-08
* [Perl] DBIx::Skinnyに色々機能を追加してみる 〜 DBIC_TRACEみたいなもの
DBIx::Skinnyでは、環境変数SKINNY_PROFILEに真値を渡せばプロファイラにSQLステートメントとバインド値が記録されます。ただし、実際にデータを確認するには手動で出力しないといけないのと、どんなタイミングで発行されたかがわかりません。でもデバッグしていると発行時に即データがみたいことがあります。なので、それ用のプロファイラを。
package Your::Model; use DBIx::Skinny::Profiler::ProfileLogger; use DBIx::Skinny setup => +{ dsn => 'dbi:SQLite:', username => '', password => '', profiler => DBIx::Skinny::Profiler::ProfileLogger->new, };
セットアプ後なら:
my $skinny = Your::Model->new; $skinny->attribute->{ profiler } = DBIx::Skinny::Profiler::ProfileLogger->new;
デフォルトでSTDERRに出力します。1=/path/to/fileのようにすると、DBIC_TRACE同様、ファイルに吐き出します。 p5-dbix-skinny-profiler-profilelogger
* [Perl] DBIx::Skinnyに色々機能を追加してみる 〜 ネストしたトランザクション
DBIx::Skinnyは下記のようなネストしたトランザクションを扱いません。でも使えると便利なこともあるのでtxn_*メソッドが対応できるようにするモジュールを作ってみました。
package Your::Model; use DBIx::Skinny; use DBIx::Skinny::Plus::NestedTransaction; # # { my $txn = Your::Model->txn_scope; { my $txn_sub = Your::Model->txn_scope; ... } ... }
おまけの機能として、SKINNY_PROFILEをonにしてるとprofilerにBEGIN WORKとかCOMMITとかを渡します。 ←取り込んでもらえました。 p5-dbix-skinny-plus-nestedtxn
* [Perl] DBIx::Skinnyに色々機能を追加してみる 〜 複数主キー
DBIx::Skinnyは単一のプライマリキーを前提としています。あまり複数プライマリキーは良くないと言われますし、作者のnekokakさんに聞いたら必要としなかったということでしたので、これはこれで割り切ってしまうのが良いのでしょう。ただそれでも、何かの事情で複数キーを設定している所でもDBIx::Skinnyを使いたいこともあるかもしれません。
そこで複数に対応させようとソースを見たところ、pkに設定した値が利用されるのは、insertとfetchした後のRowクラスにおけるupdate、deleteだけのようです。さらにinsertで使うのは、serialやauto_incrementで自動生成されたidを設定するためでした。なので、Rowクラスにあるupdate、delete時に自動でプライマリキーを設定する部分だけを対応させればよいようです。で、つくったのがDBIx::Skinny::Plus::MultiPK。
pakcage Your::Model; use DBIx::Skinny setup => +{ dsn => 'dbi:SQLite:', username => '', password => '', }; use DBIx::Skinny::Plus::MultiPK; # ... package Your::Model::Schema; install_table 'a_multi_pk_table' => schema { pk [ qw( id_a id_b ) ]; columns qw( id_a id_b etc ); };
use DBIx::Skinnyの後で呼び出して、後はSchema内のpkにリストリファレンスでキーを渡すだけです。DBIx::Skinny::Row::_update_or_delete_condを上書きするという行儀よくない動作ですが、その辺の見直しは今後の課題。ついでにDBIx::Skinny::Row::get_columnsも上書きしています。これは、pkにリファレンスを渡す結果、insertした時にARRAY(0xa0a9d30)みたいなカラムが設定されてしまうのでget_columnsするときに取り除くため。 p5-dbix-skinny-plus-multipk
追記:コメントにありますように、本家に取り込んでもらいました。
■2010-03-18
* [Perl] DBIx::Skinny関連モジュール
先日書いたDBIx::Skinny関連のモジュールは3つとも本体に取り込んでいただけました。これらの機能はもうDBIx::Skinny(0.0705以降)だけで実現できます。昨日入れ違いでDBIx-Skinny-Profiler-ProfileLoggerをCPANにアップしたので、後で削除の予定。
で、DBIx::Skinny::DBICTicはちょこちょこアップデートしていて、joinの値にハッシュリファレンスを渡すことでリレーションのリレーションにも対応。
my $rs = $db->result_dbictic( 'user', { 'user.id' => 123 }, { 'join' => [ 'status', { 'books' => 'author' } ], '+select' => [ 'status.flag', 'author.name' ], '+as' => [ 'status', 'author_name' ], } );
このモジュールは本体のテーブルのエイリアスに'me'をつけたりしませんのでご安心ください。
_ nekokak [multi pk supportをSkinny本体にとりこんでみました。 http://github.com/ne..]
_ まかまか [すいません、コメントがspamフィルタにかかってました。ありがとうございます!]