[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