From: Peter Rabbitson Date: Sun, 28 Sep 2008 18:46:08 +0000 (+0000) Subject: mst is right: there is no sane way to allow automatic inflation with HRI, as most... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e1540ee0230804b9bc519357b703a9d1f09bce7b;p=dbsrgits%2FDBIx-Class-Historic.git mst is right: there is no sane way to allow automatic inflation with HRI, as most core inflation components rely on being passed a live row object. Ripping all related code away --- diff --git a/Changes b/Changes index 7aede42..f709857 100644 --- a/Changes +++ b/Changes @@ -10,10 +10,6 @@ Revision history for DBIx::Class path across multiple versions (jgoulah) - Better (and marginally faster) implementation of the HashRefInflator hash construction algorithm - - Added the ability to instantiate HashRefInflator so options can be - passed to the constructor - - Additional recursive function to optionally inflate any inflatable - values in the hashref generated by HashRefInflator - Allow explicit specification of ON DELETE/ON UPDATE constraints when using the SQLT parser diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 6717ea7..9155973 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -749,17 +749,6 @@ To do this simply use L. Wasn't that easy? -=head2 Skip row object creation for faster results, but still inflate -column values to the corresponding objects - - my $rs = $schema->resultset('CD'); - - $rs->result_class(DBIx::Class::ResultClass::HashRefInflator->new ( - inflate_columns => 1 - )); - - my $hash_ref = $rs->find(1); - =head2 Get raw data for blindingly fast results If the L solution diff --git a/lib/DBIx/Class/ResultClass/HashRefInflator.pm b/lib/DBIx/Class/ResultClass/HashRefInflator.pm index 9bbf65b..5fffad4 100644 --- a/lib/DBIx/Class/ResultClass/HashRefInflator.pm +++ b/lib/DBIx/Class/ResultClass/HashRefInflator.pm @@ -12,11 +12,7 @@ DBIx::Class::ResultClass::HashRefInflator use DBIx::Class::ResultClass::HashRefInflator; my $rs = $schema->resultset('CD'); - $rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); - or - $rs->result_class(DBIx::Class::ResultClass::HashRefInflator->new (%args)); - while (my $hashref = $rs->next) { ... } @@ -29,24 +25,6 @@ from a massive resultset, while skipping the creation of fancy row objects. Specifying this class as a C for a resultset will change C<< $rs->next >> to return a plain data hash-ref (or a list of such hash-refs if C<< $rs->all >> is used). -There are two ways of using this class: - -=over - -=item * - -Supply an instance of DBIx::Class::ResultClass::HashRefInflator to -C<< $rs->result_class >>. See L for a list of valid -arguments to new(). - -=item * - -Another way is to simply supply the class name as a string to -C<< $rs->result_class >>. Equivalent to passing -DBIx::Class::ResultClass::HashRefInflator->new(). - -=back - There are two ways of applying this class to a resultset: =over @@ -103,91 +81,19 @@ $mk_hash = sub { } }; -# This is the inflator -my $inflate_hash; -$inflate_hash = sub { - my ($hri_instance, $schema, $rc, $data) = @_; - - foreach my $column (keys %{$data}) { - - if (ref $data->{$column} eq 'HASH') { - $inflate_hash->($hri_instance, $schema, $schema->source ($rc)->related_class ($column), $data->{$column}); - } - elsif (ref $data->{$column} eq 'ARRAY') { - foreach my $rel (@{$data->{$column}}) { - $inflate_hash->($hri_instance, $schema, $schema->source ($rc)->related_class ($column), $rel); - } - } - else { - # "null is null is null" - next if not defined $data->{$column}; - - # cache the inflator coderef - unless (exists $hri_instance->{_inflator_cache}{$rc}{$column}) { - $hri_instance->{_inflator_cache}{$rc}{$column} = exists $schema->source ($rc)->_relationships->{$column} - ? undef # currently no way to inflate a column sharing a name with a rel - : $rc->column_info($column)->{_inflate_info}{inflate} - ; - } - - if ($hri_instance->{_inflator_cache}{$rc}{$column}) { - $data->{$column} = $hri_instance->{_inflator_cache}{$rc}{$column}->($data->{$column}); - } - } - } -}; - - =head1 METHODS -=head2 new - - $class->new( %args ); - $class->new({ %args }); - -Creates a new DBIx::Class::ResultClass::HashRefInflator object. Takes the following -arguments: - -=over - -=item inflate_columns - -Sometimes you still want all your data to be inflated to the corresponding -objects according to the rules you defined in your table classes (e.g. you -want all dates in the resulting hash to be replaced with the equivalent -DateTime objects). Supplying C<< inflate_columns => 1 >> to the constructor will -interrogate the processed columns and apply any inflation methods declared -via L to the contents of the -resulting hash-ref. - -=back - -=cut - -sub new { - my $self = shift; - my $args = { (ref $_[0] eq 'HASH') ? %{$_[0]} : @_ }; - return bless ($args, $self) -} - =head2 inflate_result Inflates the result and prefetched data into a hash-ref (invoked by L) =cut - +################################################################################## +# inflate_result is invoked as: +# HRI->inflate_result ($resultsource_instance, $main_data_hashref, $prefetch_data_hashref) sub inflate_result { - my ($self, $source, $me, $prefetch) = @_; - - my $hashref = $mk_hash->($me, $prefetch); - - # if $self is an instance and inflate_columns is set - if ( (ref $self) and $self->{inflate_columns} ) { - $inflate_hash->($self, $source->schema, $source->result_class, $hashref); - } - - return $hashref; + return $mk_hash->($_[2], $_[3]); } @@ -210,12 +116,6 @@ C<$first> will B be a hashref, it will be a normal CD row since HashRefInflator only affects resultsets at inflation time, and prefetch causes relations to be inflated when the master C<$artist> row is inflated. -=item * - -When using C, the inflation method lookups are cached in the -HashRefInflator object for additional speed. If you modify column inflators at run -time, make sure to grab a new instance of this class to avoid cached surprises. - =back =cut diff --git a/t/68inflate_resultclass_hashrefinflator.t b/t/68inflate_resultclass_hashrefinflator.t index e8fe25b..214e11a 100644 --- a/t/68inflate_resultclass_hashrefinflator.t +++ b/t/68inflate_resultclass_hashrefinflator.t @@ -3,8 +3,6 @@ use warnings; use Test::More qw(no_plan); use lib qw(t/lib); -use Scalar::Util qw/blessed/; -use DateTime; use DBICTest; use DBIx::Class::ResultClass::HashRefInflator; my $schema = DBICTest->init_schema(); @@ -117,36 +115,3 @@ for my $index (0 .. $#hashrefinf) { is ($track->get_column ($col), $datahashref->{cds}{tracks}{$col}, "Correct track '$col'"); } } - -# Test the data inflator - -is_deeply ( - DBIx::Class::ResultClass::HashRefInflator->new (inflate_columns => 1), - DBIx::Class::ResultClass::HashRefInflator->new ({inflate_columns => 1}), - 'Make sure arguments as list and as hashref work identically' -); - -$schema->class('CD')->inflate_column( 'year', - { inflate => sub { DateTime->new( year => shift ) }, - deflate => sub { shift->year } } -); - -my $cd_rs = $schema->resultset("CD")->search ({cdid => 3}); -$cd_rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); - -my $cd = $cd_rs->first; -ok ( (not blessed $cd->{year}), "Plain string returned for year"); -is ( $cd->{year}, '1997', "We are looking at the right year"); - -# try again with a HRI instance -$cd_rs->reset; -$cd_rs->result_class(DBIx::Class::ResultClass::HashRefInflator->new); -my $cd2 = $cd_rs->first; -is_deeply ($cd, $cd2, "HRI used as instance returns the same hashref as the old result_class ('class')"); - -# try it again with inflation requested -$cd_rs->reset; -$cd_rs->result_class(DBIx::Class::ResultClass::HashRefInflator->new (inflate_columns => 1)); -my $cd3 = $cd_rs->first; -isa_ok ($cd3->{year}, 'DateTime', "Inflated object"); -is ($cd3->{year}, DateTime->new ( year => 1997 ), "Correct year was inflated");