From: Peter Rabbitson Date: Mon, 10 May 2010 11:39:56 +0000 (+0000) Subject: Maintain full coherence between filtered cache and unfiltered results, including... X-Git-Tag: v0.08122~72^2~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=491c8ff9f0bd64d1d74b94ad1b0dd5fef37eb52a;p=dbsrgits%2FDBIx-Class.git Maintain full coherence between filtered cache and unfiltered results, including store_column --- diff --git a/lib/DBIx/Class/FilterColumn.pm b/lib/DBIx/Class/FilterColumn.pm index a6bda53..9002058 100644 --- a/lib/DBIx/Class/FilterColumn.pm +++ b/lib/DBIx/Class/FilterColumn.pm @@ -66,7 +66,28 @@ sub get_filtered_column { return $self->{_filtered_column}{$col} = $self->_column_from_storage($col, $val); } -sub set_column { +sub get_column { + my ($self, $col) = @_; + if (exists $self->{_filtered_column}{$col}) { + return $self->{_column_data}{$col} ||= $self->_column_to_storage ($col, $self->{_filtered_column}{$col}); + } + + return $self->next::method ($col); +} + +# sadly a separate codepath in Row.pm ( used by insert() ) +sub get_columns { + my $self = shift; + + foreach my $col (keys %{$self->{_filtered_column}||{}}) { + $self->{_column_data}{$col} ||= $self->_column_to_storage ($col, $self->{_filtered_column}{$col}) + if exists $self->{_filtered_column}{$col}; + } + + $self->next::method (@_); +} + +sub store_column { my ($self, $col) = (shift, @_); # blow cache @@ -89,19 +110,23 @@ sub set_filtered_column { $self->set_column($col, $self->_column_to_storage($col, $filtered)); - return $filtered; + return $self->{_filtered_column}{$col} = $filtered; } sub update { my ($self, $attrs, @rest) = @_; + foreach my $key (keys %{$attrs||{}}) { - if ($self->has_column($key) && - exists $self->column_info($key)->{_filter_info}) { - my $val = delete $attrs->{$key}; - $self->set_filtered_column($key, $val); - $attrs->{$key} = $self->_column_to_storage($key, $val) + if ( + $self->has_column($key) + && + exists $self->column_info($key)->{_filter_info} + ) { + $self->set_filtered_column($key, delete $attrs->{$key}); + $self->get_column($key); } } + return $self->next::method($attrs, @rest); } @@ -114,10 +139,10 @@ sub new { foreach my $key (keys %{$attrs||{}}) { if ($obj->has_column($key) && exists $obj->column_info($key)->{_filter_info} ) { - my $val = delete $attrs->{$key}; - $obj->set_filtered_column($key, $val); + $obj->set_filtered_column($key, $attrs->{$key}); } } + return $obj; } diff --git a/t/03podcoverage.t b/t/03podcoverage.t index 0b2bbbe..095a2d2 100644 --- a/t/03podcoverage.t +++ b/t/03podcoverage.t @@ -50,7 +50,9 @@ my $exceptions = { ignore => [qw/ new update - set_column + store_column + get_column + get_columns /], }, 'DBIx::Class::ResultSource' => { diff --git a/t/row/filter_column.t b/t/row/filter_column.t index ef2b880..e896cc9 100644 --- a/t/row/filter_column.t +++ b/t/row/filter_column.t @@ -96,10 +96,6 @@ CACHE_TEST: { ok ($artist->is_column_changed ('rank'), 'Column marked as dirty'); $artist->rank; - is $from_storage_ran, ++$expected_from, 'from ran once'; - is $to_storage_ran, $expected_to, 'to did not run'; - - $artist->rank; is $from_storage_ran, $expected_from, 'from did not run'; is $to_storage_ran, $expected_to, 'to did not run'; @@ -119,17 +115,8 @@ CACHE_TEST: { $artist->store_column(rank => 4); ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on differing store_column value'); - is ($artist->rank, '6', 'Filtered column still contains old value (cache not blown)'); - is $from_storage_ran, $expected_from, 'from did not run'; - is $to_storage_ran, $expected_to, 'to did not run'; - - $artist->set_column(rank => 4); - TODO: { - local $TODO = 'There seems to be no way around that much wizardry... which is ok'; - ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on out-of-sync set_column value'); - } - is ($artist->rank, '8', 'Column set properly (cache blown)'); - is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)'; + is ($artist->rank, '8', 'Cache properly blown'); + is $from_storage_ran, ++$expected_from, 'from did not run'; is $to_storage_ran, $expected_to, 'to did not run'; }