From: Ash Berlin Date: Fri, 5 Jan 2007 14:59:01 +0000 (+0000) Subject: Added abraxa's HashRefInflator (no docs as yet) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b0930c1e503ce8b2bd0329323851fe6ca3942cd0;p=dbsrgits%2FDBIx-Class-Historic.git Added abraxa's HashRefInflator (no docs as yet) --- diff --git a/Changes b/Changes index 26aa117..f7ac47c 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,7 @@ Revision history for DBIx::Class - add support to Ordered for multiple ordering columns - mark DB.pm and compose_connection as deprecated - switch tests to compose_namespace + - ResltClass::HashRefInflator added 0.07999_01 2006-10-05 21:00:00 - add connect_info option "disable_statement_caching" diff --git a/lib/DBIx/Class/ResultClass/HashRefInflator.pm b/lib/DBIx/Class/ResultClass/HashRefInflator.pm new file mode 100644 index 0000000..d7dd411 --- /dev/null +++ b/lib/DBIx/Class/ResultClass/HashRefInflator.pm @@ -0,0 +1,24 @@ +package DBIx::Class::ResultClass::HashRefInflator; + +# $me is the hashref of cols/data from the immediate resultsource +# $rest is a deep hashref of all the data from the prefetched +# related sources. + +sub mk_hash { + my ($me, $rest) = @_; + + # to avoid emtpy has_many rels contain one empty hashref + return if (not keys %$me); + + return { %$me, + map { ($_ => ref($rest->{$_}[0]) eq 'ARRAY' ? [ map { mk_hash(@$_) } @{$rest->{$_}} ] : mk_hash(@{$rest->{$_}}) ) } keys %$rest + }; +} + +sub inflate_result { + my ($self, $source, $me, $prefetch) = @_; + + return mk_hash($me, $prefetch); +} + +1; diff --git a/t/68inflate_resultclass_hashrefinflator.t b/t/68inflate_resultclass_hashrefinflator.t new file mode 100644 index 0000000..221626a --- /dev/null +++ b/t/68inflate_resultclass_hashrefinflator.t @@ -0,0 +1,87 @@ +use strict; +use warnings; + +use Test::More qw(no_plan); +use lib qw(t/lib); +use DBICTest; +use DBIx::Class::ResultClass::HashRefInflator; +my $schema = DBICTest->init_schema(); + + +# Under some versions of SQLite if the $rs is left hanging around it will lock +# So we create a scope here cos I'm lazy +{ + my $rs = $schema->resultset('CD'); + + # get the defined columns + my @dbic_cols = sort $rs->result_source->columns; + + # use the hashref inflator class as result class + $rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); + + # fetch first record + my $datahashref1 = $rs->first; + + my @hashref_cols = sort keys %$datahashref1; + + is_deeply( \@dbic_cols, \@hashref_cols, 'returned columns' ); +} + + +sub check_cols_of { + my ($dbic_obj, $datahashref) = @_; + + foreach my $col (keys %$datahashref) { + # plain column + if (not ref ($datahashref->{$col}) ) { + is ($datahashref->{$col}, $dbic_obj->get_column($col), 'same value'); + } + # related table entry (belongs_to) + elsif (ref ($datahashref->{$col}) eq 'HASH') { + check_cols_of($dbic_obj->$col, $datahashref->{$col}); + } + # multiple related entries (has_many) + elsif (ref ($datahashref->{$col}) eq 'ARRAY') { + my @dbic_reltable = $dbic_obj->$col; + my @hashref_reltable = @{$datahashref->{$col}}; + + is (scalar @hashref_reltable, scalar @dbic_reltable, 'number of related entries'); + + # for my $index (0..scalar @hashref_reltable) { + for my $index (0..scalar @dbic_reltable) { + my $dbic_reltable_obj = $dbic_reltable[$index]; + my $hashref_reltable_entry = $hashref_reltable[$index]; + + check_cols_of($dbic_reltable_obj, $hashref_reltable_entry); + } + } + } +} + +# create a cd without tracks for testing empty has_many relationship +$schema->resultset('CD')->create({ title => 'Silence is golden', artist => 3, year => 2006 }); + +# order_by to ensure both resultsets have the rows in the same order +my $rs_dbic = $schema->resultset('CD')->search(undef, + { + prefetch => [ qw/ artist tracks / ], + order_by => [ 'me.cdid', 'tracks.position' ], + } +); +my $rs_hashrefinf = $schema->resultset('CD')->search(undef, + { + prefetch => [ qw/ artist tracks / ], + order_by => [ 'me.cdid', 'tracks.position' ], + } +); +$rs_hashrefinf->result_class('DBIx::Class::ResultClass::HashRefInflator'); + +my @dbic = $rs_dbic->all; +my @hashrefinf = $rs_hashrefinf->all; + +for my $index (0..scalar @hashrefinf) { + my $dbic_obj = $dbic[$index]; + my $datahashref = $hashrefinf[$index]; + + check_cols_of($dbic_obj, $datahashref); +}