[Bast-commits] r7501 - in DBIx-Class/0.08/branches/prefetch:
lib/DBIx/Class t/prefetch
ribasushi at dev.catalyst.perl.org
ribasushi at dev.catalyst.perl.org
Thu Sep 3 14:11:08 GMT 2009
Author: ribasushi
Date: 2009-09-03 14:11:07 +0000 (Thu, 03 Sep 2009)
New Revision: 7501
Added:
DBIx-Class/0.08/branches/prefetch/t/prefetch/_util.t
Modified:
DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm
DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm
Log:
First part of refactor
Modified: DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm 2009-09-03 09:36:58 UTC (rev 7500)
+++ DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm 2009-09-03 14:11:07 UTC (rev 7501)
@@ -966,86 +966,7 @@
return @new;
}
-# _unflatten_result takes a row hashref which looks like this:
-# $VAR1 = {
-# 'cd.artist.artistid' => '1',
-# 'cd.artist' => '1',
-# 'cd_id' => '1',
-# 'cd.genreid' => undef,
-# 'cd.year' => '1999',
-# 'cd.title' => 'Spoonful of bees',
-# 'cd.single_track' => undef,
-# 'cd.artist.name' => 'Caterwauler McCrae',
-# 'cd.artist.rank' => '13',
-# 'cd.artist.charfield' => undef,
-# 'cd.cdid' => '1'
-# };
-# and generates the following structure:
-
-# $VAR1 = [
-# {
-# 'cd_id' => '1'
-# },
-# {
-# 'cd' => [
-# {
-# 'single_track' => undef,
-# 'cdid' => '1',
-# 'artist' => '1',
-# 'title' => 'Spoonful of bees',
-# 'year' => '1999',
-# 'genreid' => undef
-# },
-# {
-# 'artist' => [
-# {
-# 'artistid' => '1',
-# 'charfield' => undef,
-# 'name' => 'Caterwauler McCrae',
-# 'rank' => '13'
-# }
-# ]
-# }
-# ]
-# }
-# ];
-
-# It returns one row object which consists of an arrayref with two
-# elements. The first contains the plain column data, the second
-# contains the data of relationships. Those are row arrayrefs, themselves.
-
-# it's a recursive function. It needs to request the relationship_info
-# to decide whether to put the data of a relationship in a hashref
-# (i.e. belongs_to) or an arrayref (i.e. has_many).
-
-sub _unflatten_result {
- my ( $self, $row ) = @_;
-
- my $columns = {};
- my $rels = {};
-
- foreach my $column ( sort keys %$row ) {
- if ( $column =~ /^(.*?)\.(.*)$/ ) {
- $rels->{$1} ||= {};
- $rels->{$1}->{$2} = $row->{$column};
- }
- else {
- $columns->{$column} = $row->{$column};
- }
- }
-
- foreach my $rel ( sort keys %$rels ) {
- my $rel_info = $self->result_source->relationship_info($rel);
- $rels->{$rel} =
- $self->related_resultset($rel)->_unflatten_result( $rels->{$rel} );
- $rels->{$rel} = [ $rels->{$rel} ]
- if ( $rel_info->{attrs}->{accessor} eq 'multi' );
- }
-
- return keys %$rels ? [ $columns, $rels ] : [$columns];
-}
-
# two arguments: $as_proto is an arrayref of column names,
# $row_ref is an arrayref of the data. If none of the row data
# is defined we return undef (that's copied from the old
@@ -1077,7 +998,7 @@
do {
my $i = 0;
my $row = { map { $_ => $row[ $i++ ] } @$as_proto };
- $row = $self->_unflatten_result($row);
+ $row = $self->result_source->_parse_row($row);
unless ( scalar @$rows ) {
push( @$rows, $row );
}
Modified: DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm 2009-09-03 09:36:58 UTC (rev 7500)
+++ DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm 2009-09-03 14:11:07 UTC (rev 7501)
@@ -1479,6 +1479,41 @@
}
}
+# Takes a hashref of $sth->fetchrow values keyed to the corresponding
+# {as} dbic aliases, and splits it into a native columns hashref
+# (as in $row->get_columns), followed by any non-native (prefetched)
+# columns, presented in a nested structure resembling an HRI dump.
+# The structure is constructed taking into account relationship metadata
+# (single vs multi).
+# The resulting arrayref resembles the arguments to ::Row::inflate_result
+# For an example look at t/prefetch/_util.t:
+sub _parse_row {
+ my ( $self, $row ) = @_;
+
+ my ($me, $pref);
+
+ foreach my $column ( keys %$row ) {
+ if ( $column =~ /^ ([^\.]+) \. (.*) $/x ) {
+ $pref->{$1}{$2} = $row->{$column};
+ }
+ else {
+ $me->{$column} = $row->{$column};
+ }
+ }
+
+ foreach my $rel ( keys %{$pref||{}} ) {
+ my $rel_info = $self->relationship_info($rel);
+
+ $pref->{$rel} =
+ $self->related_source($rel)->_parse_row( $pref->{$rel} );
+
+ $pref->{$rel} = [ $pref->{$rel} ]
+ if ( $rel_info->{attrs}{accessor} eq 'multi' );
+ }
+
+ return [ $me||{}, $pref||() ];
+}
+
=head2 related_source
=over 4
Added: DBIx-Class/0.08/branches/prefetch/t/prefetch/_util.t
===================================================================
--- DBIx-Class/0.08/branches/prefetch/t/prefetch/_util.t (rev 0)
+++ DBIx-Class/0.08/branches/prefetch/t/prefetch/_util.t 2009-09-03 14:11:07 UTC (rev 7501)
@@ -0,0 +1,105 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema(no_deploy => 1);
+
+
+my $irow = $schema->source ('Artwork')->_parse_row (
+ {
+ 'cd_id' => '1',
+
+ 'artwork_to_artist.artist_id' => '2',
+ 'artwork_to_artist.artwork_cd_id' => '1',
+
+ 'cd.artist' => '1',
+ 'cd.cdid' => '1',
+ 'cd.title' => 'Spoonful of bees',
+
+ 'cd.artist.artistid' => '1',
+ 'cd.artist.name' => 'Caterwauler McCrae',
+ },
+);
+
+is_deeply (
+ $irow,
+ [
+ {
+ 'cd_id' => '1'
+ },
+ {
+ 'artwork_to_artist' => [
+ [
+ {
+ 'artist_id' => '2',
+ 'artwork_cd_id' => '1'
+ }
+ ]
+ ],
+
+ 'cd' => [
+ {
+ 'artist' => '1',
+ 'cdid' => '1',
+ 'title' => 'Spoonful of bees',
+ },
+ {
+ 'artist' => [
+ {
+ 'artistid' => '1',
+ 'name' => 'Caterwauler McCrae',
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ '_parse_row works as expected',
+);
+
+$irow = $schema->source ('Artist')->_parse_row (
+ {
+ 'name' => 'Caterwauler McCrae',
+ 'cds.tracks.cd' => '3',
+ 'cds.tracks.title' => 'Fowlin',
+ 'cds.tracks.cd_single.title' => 'Awesome single',
+ }
+);
+is_deeply (
+ $irow,
+ [
+ {
+ 'name' => 'Caterwauler McCrae'
+ },
+ {
+ 'cds' => [
+ [
+ {},
+ {
+ 'tracks' => [
+ [
+ {
+ 'cd' => '3',
+ 'title' => 'Fowlin'
+ },
+ {
+ 'cd_single' => [
+ {
+ title => 'Awesome single',
+ },
+ ],
+ },
+ ]
+ ]
+ }
+ ]
+ ]
+ }
+ ],
+ '_parse_row works over missing joins',
+);
+
+done_testing;
More information about the Bast-commits
mailing list