X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FFilterColumn.pm;h=0cfcdfcf0d8d1dbb841173ba9a31f545d8da563b;hb=22d9e05a39b5afbac794a5af9e83b4a38f766ac4;hp=2425986e2c170b8e2363803c778f022bfbbd97af;hpb=956f4141284c6b2f216de47a09ffa16928df38fc;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/FilterColumn.pm b/lib/DBIx/Class/FilterColumn.pm index 2425986..0cfcdfc 100644 --- a/lib/DBIx/Class/FilterColumn.pm +++ b/lib/DBIx/Class/FilterColumn.pm @@ -16,12 +16,12 @@ sub filter_column { $self->column_info($col)->{_filter_info} = $attrs; my $acc = $self->column_info($col)->{accessor}; - $self->mk_group_accessors('filtered_column' => [ (defined $acc ? $acc : $col), $col]); + $self->mk_group_accessors(filtered_column => [ (defined $acc ? $acc : $col), $col]); return 1; } -sub _filtered_column { - my ($self, $col, $value) = @_; +sub _column_from_storage { + my ($self, $source, $col, $value) = @_; return $value unless defined $value; @@ -30,26 +30,26 @@ sub _filtered_column { return $value unless exists $info->{_filter_info}; - my $filter = $info->{_filter_info}{filter}; + my $filter = $info->{_filter_info}{filter_from_storage}; $self->throw_exception("No inflator for $col") unless defined $filter; - return $self->$filter($value); + return $source->$filter($value); } -sub _unfiltered_column { - my ($self, $col, $value) = @_; +sub _column_to_storage { + my ($self, $source, $col, $value) = @_; my $info = $self->column_info($col) or $self->throw_exception("No column info for $col"); return $value unless exists $info->{_filter_info}; - my $unfilter = $info->{_filter_info}{unfilter}; + my $unfilter = $info->{_filter_info}{filter_to_storage}; $self->throw_exception("No unfilter for $col") unless defined $unfilter; - return $self->$unfilter($value); + return $source->$unfilter($value); } -sub get_value { +sub get_filtered_column { my ($self, $col) = @_; $self->throw_exception("$col is not a filtered column") @@ -60,31 +60,84 @@ sub get_value { my $val = $self->get_column($col); - return $self->{_filtered_column}{$col} = $self->_filtered_column($col, $val); + return $self->{_filtered_column}{$col} = $self->_column_from_storage($self->result_source, $col, $val); } -sub set_value { +sub set_filtered_column { my ($self, $col, $filtered) = @_; - $self->set_column($col, $self->_unfiltered_column($col, $filtered)); + $self->set_column($col, $self->_column_to_storage($self->result_source, $col, $filtered)); delete $self->{_filtered_column}{$col}; return $filtered; } -sub register_column { - my ($class, $col, $info) = @_; - my $acc = $col; - if (exists $info->{accessor}) { - return unless defined $info->{accessor}; - $acc = [ $info->{accessor}, $col ]; +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($self->result_source, $key, $val) + } } - if ( exists $self->column_info($col)->{_filter_info} ) { - $class->mk_group_accessors(value => $acc); - } else { - $class->mk_group_accessors(column => $acc); + return $self->next::method($attrs, @rest); +} + + +sub new { + my ($class, $attrs, @rest) = @_; + my $source = delete $attrs->{-result_source} + or $class->throw_exception('Sourceless rows are not supported with DBIx::Class::FilterColumn'); + + foreach my $key (keys %{$attrs||{}}) { + if ($class->has_column($key) && + exists $class->column_info($key)->{_filter_info} ) { + $attrs->{$key} = $class->_column_to_storage($source, $key, delete $attrs->{$key}) + } } + my $obj = $class->next::method($attrs, @rest); + return $obj; } 1; + +=head1 THE ONE TRUE WAY + + package My::Reusable::Filter; + + sub to_pennies { $_[1] * 100 } + sub from_pennies { $_[1] / 100 } + + 1; + + package My::Schema::Result::Account; + + use strict; + use warnings; + + use base 'DBIx::Class::Core'; + + __PACKAGE->load_components('FilterColumn'); + + __PACKAGE__->add_columns( + id => { + data_type => 'int', + is_auto_increment => 1, + }, + total_money => { + data_type => 'int', + }, + ); + + __PACKAGE__->set_primary_key('id'); + + __PACKAGE__->filter_column(total_money => { + filter_to_storage => 'to_pennies', + filter_from_storage => 'from_pennies', + }); + + 1; +