ziguzagu.org

Class::DBI::Sweetを継承する順番

Class::DBI::Sweetと、他のClass::DBIを継承するモジュール(Class::DBI::mysql)とかを一緒に使う(use baseする)場合は、Class::DBI::Sweetを最初に継承しないといけないっぽい、でした。

#!/usr/bin/perl
package DB;
use strict;
use base qw(Class::DBI::mysql Class::DBI::Sweet);
__PACKAGE__->connection("dbi:mysql:test", "test", "", { RaiseError => 1 });

package DB::Item;
use strict;
use base qw(DB);
__PACKAGE__->set_up_table('item');

package main;
use strict;
use warnings;

my ($page, $it) = DB::Item->page(
    {}, { rows => 5, page => 1, order_by => "id" }
);
while (my $item = $it->next()) {
    print join ",", $item->id, $item->subject, $item->body, "\n";
}

use base が、

use base qw(Class::DBI::mysql Class::DBI::Sweet);

この順番だと、DB::Item->pageがつくったSQLは、

SELECT id
FROM   item
WHERE

当然えらー。

: DBD::mysql::st execute failed: Something is wrong in your syntax  : '' 付近  : 3 行目 [for Statement "SELECT id
FROM   item
WHERE
"] at /usr/local/share/perl/5.8.4/DBIx/ContextualFetch.pm line 52.
 at /usr/local/share/perl/5.8.4/Class/DBI/Search/Basic.pm line 169

で、use baseを

use base qw(Class::DBI::Sweet Class::DBI::mysql);

とすると問題なしで、意図していたSQLを作ってくれます。

SELECT me.id
FROM   item me
WHERE  1=1   ORDER BY id  LIMIT 0, 5

Class::DBI::Loaderでも、newメソッドのオプションにleft_base_classesというのがあって、

List of additional base classes, that need to be leftmost, for example Class::DBI::Sweet (former Catalyst::Model::CDBI::Sweet).

と書かれているので、Class::DBIの拡張もの(PluginじゃなくてCDBIを継承してるもの)は継承順番がけっこうシビアだったりするのかしら。。。

というところまではわかりましたが、なんで最初に継承しないといけないのかとかはまだ調べてないので不明。よくわからんけどとりあえず動いてる、というなんか一番いやな状態のままです。。。