Class::DBIでのessentialの動的指定のバグ

| コメント(0) | トラックバック(0)
あー 超絶はまった・・・ 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/ほげほげ/);
とかした際の実態なのだが、 このメソッドではグループの追加は行っていてもグループの削除はしていない。 それが原因。 あー眠い・・・・

トラックバック(0)

トラックバックURL: http://deathmarch.orz.hm/mt/mt-tb.fcgi/62

コメントする