あー 超絶はまった・・・
Class::DBIにて、動的にEssentialを指定するとおかしくなるバグがある。
動的に というか、2回以上。
http://rt.cpan.org/Public/Bug/Display.html?id=14798
こんな風にrtCPANにも乗ってます。
1年前から超絶放置中。
まぁ もともと$model->columns(Essential => qw/hoge fuga moge/);
っていうの自体動的にやること考慮されていないんだろうけど、
普段はIDだけの高速引きで、時と場合によっては必要な分だけ引きたいというのは結構ある。
あらかじめ必要な分を引いてやらなければ、ループでその行を使うたびにPrimaryKeyでのSELECTが走るからだ。
(10万行のテーブルとかだと全体へのsearchが1回。
あとはループで各行へのPrimaryKey引きが1回ずつの
合計10万1回SQLが走るとかエグいことになる)
結論から言えば、
Class::DBI::ColumnGrouperのadd_groupメソッドを以下のように変えてやれば直る。
続きにて簡単な例をば。sub add_group { my ($self, $group, @names) = @_; $self->add_group(Primary => $names[0]) if ($group eq "All" or $group eq "Essential") and not $self->group_cols('Primary'); $self->add_group(Essential => @names) if $group eq "All" and !$self->essential; @names = _unique($self->primary, @names) if $group eq "Essential"; my @cols = map $self->add_column($_), @names; unless($group eq "All") { foreach my $col ($self->all_columns) { delete $col->{_groups}->{$group} if(exists $col->{_groups}->{$group}); } } $_->add_group($group) foreach @cols; $self->{_groups}->{$group} = \@cols; return $self; }
__PACKAGE__->table('group_master');
__PACKAGE__->columns(Primary => 'id');
__PACKAGE__->columns(All => qw(id disable name memo admin_only));
こんな定義のテーブルがあったとして、
SELECT id, admin_only, name FROM table;とかいうSQLを発行したい場合に発生する。 こんな場合には普通に考えると
my @org_essential = $model->columns('Essential');
$model->columns('Essential' => qw/id admin_only name/);
my $it = $model->search_where(ほげほげ);
$model->columns('Essential' => @org_essential);
とかやるわけなのだが、
これをやるとテーブル側としてはEssentialはIDだけなので他をSELECTしようとするのだが、
カラム側では自分がEssentialに入っていると思っているのでSELECTが走らず値が取れなくなる。
原因はClass::DBI::ColumnGrouperというモジュールにある。
このモジュールのadd_groupというメソッドが
columns(Essential => qw/ほげほげ/);とかした際の実態なのだが、 このメソッドではグループの追加は行っていてもグループの削除はしていない。 それが原因。 あー眠い・・・・

コメントする