fixed xt/pod.t failure in Row.pm
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Row.pm
index ac12ead..0a2cf4a 100644 (file)
@@ -8,6 +8,7 @@ use base qw/DBIx::Class/;
 use Scalar::Util 'blessed';
 use List::Util 'first';
 use Try::Tiny;
+use DBIx::Class::Carp;
 
 ###
 ### Internal method
@@ -47,8 +48,8 @@ relationship accessors of L<Result|DBIx::Class::Manual::ResultClass> objects.
 =head1 NOTE
 
 All "Row objects" derived from a Schema-attached L<DBIx::Class::ResultSet>
-object (such as a typical C<< L<search|DBIx::Class::ResultSet/search
->->L<next|DBIx::Class::ResultSet/next> >> call) are actually Result
+object (such as a typical C<< L<search|DBIx::Class::ResultSet/search>->
+L<next|DBIx::Class::ResultSet/next> >> call) are actually Result
 instances, based on your application's
 L<Result class|DBIx::Class::Manual::Glossary/Result_class>.
 
@@ -718,8 +719,22 @@ sub get_columns {
   my $self = shift;
   if (exists $self->{_inflated_column}) {
     foreach my $col (keys %{$self->{_inflated_column}}) {
-      $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}))
-        unless exists $self->{_column_data}{$col};
+      unless (exists $self->{_column_data}{$col}) {
+
+        # if cached related_resultset is present assume this was a prefetch
+        carp_unique(
+          "Returning primary keys of prefetched 'filter' rels as part of get_columns() is deprecated and will "
+        . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
+        ) if (
+          ! $ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}
+            and
+          defined $self->{related_resultsets}{$col}
+            and
+          defined $self->{related_resultsets}{$col}->get_cache
+        );
+
+        $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}));
+      }
     }
   }
   return %{$self->{_column_data}};
@@ -819,19 +834,43 @@ sub get_inflated_columns {
     grep { $self->has_column_loaded($_) } $self->columns
   ]);
 
-  my %inflated;
-  for my $col (keys %$loaded_colinfo) {
-    if (exists $loaded_colinfo->{$col}{accessor}) {
-      my $acc = $loaded_colinfo->{$col}{accessor};
-      $inflated{$col} = $self->$acc if defined $acc;
-    }
-    else {
-      $inflated{$col} = $self->$col;
+  my %cols_to_return = ( %{$self->{_column_data}}, %$loaded_colinfo );
+
+  unless ($ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}) {
+    for (keys %$loaded_colinfo) {
+      # if cached related_resultset is present assume this was a prefetch
+      if (
+        $loaded_colinfo->{$_}{_inflate_info}
+          and
+        defined $self->{related_resultsets}{$_}
+          and
+        defined $self->{related_resultsets}{$_}->get_cache
+      ) {
+        carp_unique(
+          "Returning prefetched 'filter' rels as part of get_inflated_columns() is deprecated and will "
+        . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
+        );
+        last;
+      }
     }
   }
 
-  # return all loaded columns with the inflations overlayed on top
-  return %{ { $self->get_columns, %inflated } };
+  map { $_ => (
+  (
+    ! exists $loaded_colinfo->{$_}
+      or
+    (
+      exists $loaded_colinfo->{$_}{accessor}
+        and
+      ! defined $loaded_colinfo->{$_}{accessor}
+    )
+  ) ? $self->get_column($_)
+    : $self->${ \(
+      defined $loaded_colinfo->{$_}{accessor}
+        ? $loaded_colinfo->{$_}{accessor}
+        : $_
+      )}
+  )} keys %cols_to_return;
 }
 
 sub _is_column_numeric {
@@ -1183,6 +1222,24 @@ sub inflate_result {
   if ($prefetch) {
     for my $relname ( keys %$prefetch ) {
 
+      my $relinfo = $rsrc->relationship_info($relname) or do {
+        my $err = sprintf
+          "Inflation into non-existent relationship '%s' of '%s' requested",
+          $relname,
+          $rsrc->source_name,
+        ;
+        if (my ($colname) = sort { length($a) <=> length ($b) } keys %{$prefetch->{$relname}[0] || {}} ) {
+          $err .= sprintf ", check the inflation specification (columns/as) ending in '...%s.%s'",
+          $relname,
+          $colname,
+        }
+
+        $rsrc->throw_exception($err);
+      };
+
+      $class->throw_exception("No accessor type declared for prefetched relationship '$relname'")
+        unless $relinfo->{attrs}{accessor};
+
       my @rel_objects;
       if (
         $prefetch->{$relname}
@@ -1191,35 +1248,29 @@ sub inflate_result {
           and
         ref($prefetch->{$relname}) ne $DBIx::Class::ResultSource::RowParser::Util::null_branch_class
       ) {
-        my $rel_rsrc = try {
-          $rsrc->related_source($relname)
-        } catch {
-          my $err = sprintf
-            "Inflation into non-existent relationship '%s' of '%s' requested",
-            $relname,
-            $rsrc->source_name,
-          ;
-          if (my ($colname) = sort { length($a) <=> length ($b) } keys %{$prefetch->{$relname}[0] || {}} ) {
-            $err .= sprintf ", check the inflation specification (columns/as) ending in '...%s.%s'",
-            $relname,
-            $colname,
-          }
 
-          $rsrc->throw_exception($err);
-        };
+        my $rel_rs = $new->related_resultset($relname);
 
-        @rel_objects = map {
-          $rel_rsrc->result_class->inflate_result( $rel_rsrc, @$_ )
-        } ( ref $prefetch->{$relname}[0] eq 'ARRAY' ?  @{$prefetch->{$relname}} : $prefetch->{$relname} );
+        if (ref $prefetch->{$relname}[0] eq 'ARRAY') {
+          my $rel_rsrc = $rel_rs->result_source;
+          my $rel_class = $rel_rs->result_class;
+          my $rel_inflator = $rel_class->can('inflate_result');
+          @rel_objects = map
+            { $rel_class->$rel_inflator ( $rel_rsrc, @$_ ) }
+            @{$prefetch->{$relname}}
+          ;
+        }
+        else {
+          @rel_objects = $rel_rs->result_class->inflate_result(
+            $rel_rs->result_source, @{$prefetch->{$relname}}
+          );
+        }
       }
 
-      my $accessor = $rsrc->relationship_info($relname)->{attrs}{accessor}
-        or $class->throw_exception("No accessor type declared for prefetched relationship '$relname'");
-
-      if ($accessor eq 'single') {
+      if ($relinfo->{attrs}{accessor} eq 'single') {
         $new->{_relationship_data}{$relname} = $rel_objects[0];
       }
-      elsif ($accessor eq 'filter') {
+      elsif ($relinfo->{attrs}{accessor} eq 'filter') {
         $new->{_inflated_column}{$relname} = $rel_objects[0];
       }