account for coderefs partially
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index 454d00d..fcbbcc1 100644 (file)
@@ -2227,7 +2227,6 @@ case there are obviously no benefits to using this method over L</create>.
 sub populate {
   my $self = shift;
 
-
   if (defined wantarray) {
     # cruft placed in standalone method
     my $data = $self->_normalize_populate_to_hashref(@_);
@@ -2242,6 +2241,7 @@ sub populate {
     my $data = $self->_normalize_populate_to_arrayref(@_);
 
     return unless @$data;
+    use DDP; p $data;
 
     my $first = shift @$data;
 
@@ -2250,14 +2250,20 @@ sub populate {
     my (@rels, @columns);
     my $rsrc = $self->result_source;
     my $rels = { map { $_ => $rsrc->relationship_info($_) } $rsrc->relationships };
-    for my $index (0..$#$first) {
-      my $col = $first->[$index];
-      my $val = $data->[0][$index];
-      my $ref = ref $val;
-      $rels->{$col} && ($ref eq 'ARRAY' or $ref eq 'HASH')
-        ? push @rels, $col
-        : push @columns, $col
-      ;
+
+    if (ref $data->[0] eq 'CODE') {
+      @columns = @$first;
+    }
+    else {
+      for my $index (0..$#$first) {
+        my $col = $first->[$index];
+        my $val = $data->[0][$index];
+        my $ref = ref $val;
+        $rels->{$col} && ($ref eq 'ARRAY' or $ref eq 'HASH')
+          ? push @rels, $col
+          : push @columns, $col
+        ;
+      }
     }
 
     my @pks = $rsrc->primary_columns;
@@ -2265,14 +2271,18 @@ sub populate {
 
     ## do the belongs_to relationships
     foreach my $index (0..$#$data) {
+      next if (ref $data->[$index] eq 'CODE');
 
       # delegate to list context populate()/create() for any dataset without
       # primary keys with specified relationships
 
-      if (grep { defined $colmap{$_} && !defined $data->[$index][$colmap{$_}] } @pks) {
+      if (grep { !defined $colmap{$_} } @pks) {
         for my $r (@rels) {
-          if (grep { ref $data->[$index][$colmap{$_}] eq $_ } qw/HASH ARRAY/) {  # a related set must be a HASH or AoH
-            my @ret = $self->populate($data);
+          if (grep { ref $data->[$index][$colmap{$r}] eq $_ } qw/HASH ARRAY/) {  # a related set must be a HASH or AoH
+            # we pass in @_ here as it is the pre-normalized version of $data.
+            # in list/scalar context it is expecting this form so we save a step
+            # converting it back
+            my @ret = $self->populate(@_);
             return;
           }
         }
@@ -2311,6 +2321,7 @@ sub populate {
 
     ## do the has_many relationships
     foreach my $item (@$data) {
+      next if (ref $item eq  'CODE');
 
       my $main_row;
 
@@ -2328,30 +2339,25 @@ sub populate {
           $rel,
         );
 
-=begin
-        if ( ref $item->[$colmap{$rel}] eq 'ARRAY') {
-          for my $subitem (@{ $item->[$colmap{$rel}] }) {
-            $subitem->
-
+        my @rows_to_add = do {
+          if (ref $item->[ $colmap{$rel} ] eq 'ARRAY') {
+            @{$item->[$colmap{$rel}]};
           }
-        }
+          else {
+            ($item->[$colmap{$rel}]);
+          }
+        };
 
-        my @rows_to_add = ref eq 'ARRAY' ? @{$item->[$colmap{$rel}]} : ($item->[$colmap{$rel}]);
+        # only AoH supports multicreate per doc specs
         my @populate = map { {%$_, %$related} } @rows_to_add;
 
-=cut
-        $child->populate( $item->[$colmap{$rel}] );
+        $child->populate(\@populate);
       }
     }
   }
 }
 
 # populate() arguments went over several incarnations
-# can be any mixture of :
-# 1. AoA
-# 2. AoH
-# 3. AoS(calar) followed buy Arrayrefref (\@cols, $rs->as_query)
-# 4. coderef (tuple generator)
 # What we ultimately support is AoH
 sub _normalize_populate_to_hashref {
   my ($self, $arg) = @_;
@@ -2367,21 +2373,13 @@ sub _normalize_populate_to_hashref {
       my @ret;
       my @colnames = @{$arg->[0]};
       foreach my $values (@{$arg}[1 .. $#$arg]) {
-        if (ref $values eq 'ARRAY') {
-          push @ret, { map { $colnames[$_] => $values->[$_] } (0 .. $#colnames) };
-        }
-        elsif (ref $values eq 'CODE' || (ref $values eq 'REF' && ref $$values eq 'ARRAY')) {
-          push @ret, $values;
-        }
-        else {
-          $self->throw_exception('Populate expects an arrayref of either hashrefs, arrayrefs, coderefs or arrayrefrefs');
-        }
+        push @ret, { map { $colnames[$_] => $values->[$_] } (0 .. $#colnames) };
       }
       return \@ret;
     }
   }
 
-  $self->throw_exception('Populate expects an arrayref of either hashrefs, arrayrefs, coderefs or arrayrefrefs');
+  $self->throw_exception('Populate expects an arrayref of hashrefs or arrayref of arrayrefs');
 }
 
 sub _normalize_populate_to_arrayref {