Fixed dumbass typo in t/lib
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
index 4a78664..b4dbfd3 100644 (file)
@@ -7,6 +7,8 @@ use DBIx::Class::ResultSet;
 
 use Carp qw/croak/;
 
+use Storable;
+
 use base qw/DBIx::Class/;
 __PACKAGE__->load_components(qw/AccessorGroup/);
 
@@ -33,9 +35,9 @@ sub new {
   $class = ref $class if ref $class;
   my $new = bless({ %{$attrs || {}} }, $class);
   $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
-  $new->{_ordered_columns} ||= [];
-  $new->{_columns} ||= {};
-  $new->{_relationships} ||= {};
+  $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
+  $new->{_columns} = { %{$new->{_columns}||{}} };
+  $new->{_relationships} = { %{$new->{_relationships}||{}} };
   $new->{name} ||= "!!NAME NOT SET!!";
   return $new;
 }
@@ -405,6 +407,79 @@ sub resolve_condition {
   }
 }
 
+=head2 resolve_prefetch (hashref/arrayref/scalar)
+Accepts one or more relationships for the current source and returns an
+array of column names for each of those relationships. Column names are
+prefixed relative to the current source, in accordance with where they appear
+in the supplied relationships. Examples:
+
+  my $source = $schema->$resultset('Tag')->source;
+  @columns = $source->resolve_prefetch( { cd => 'artist' } );
+
+  # @columns =
+  #(
+  #  'cd.cdid',
+  #  'cd.artist',
+  #  'cd.title',
+  #  'cd.year',
+  #  'cd.artist.artistid',
+  #  'cd.artist.name'
+  #)
+
+  @columns = $source->resolve_prefetch( qw[/ cd /] );
+
+  # @columns =
+  #(
+  #   'cd.cdid',
+  #   'cd.artist',
+  #   'cd.title',
+  #   'cd.year'
+  #)
+
+  $source = $schema->resultset('CD')->source;
+  @columns = $source->resolve_prefetch( qw[/ artist producer /] );
+
+  # @columns =
+  #(
+  #  'artist.artistid',
+  #  'artist.name',
+  #  'producer.producerid',
+  #  'producer.name'
+  #)  
+  
+=cut
+
+sub resolve_prefetch {
+  my( $self, $pre, $alias ) = @_;
+  use Data::Dumper;
+  #$alias ||= $self->name;
+  #warn $alias, Dumper $pre;
+  if( ref $pre eq 'ARRAY' ) {
+    return map { $self->resolve_prefetch( $_, $alias ) } @$pre;
+  }
+  elsif( ref $pre eq 'HASH' ) {
+    my @ret =
+    map {
+      $self->resolve_prefetch($_, $alias),
+      $self->related_source($_)->resolve_prefetch( $pre->{$_}, $_ )
+    }
+    keys %$pre;
+    #die Dumper \@ret;
+    return @ret;
+  }
+  elsif( ref $pre ) {
+    croak( "don't know how to resolve prefetch reftype " . ref $pre);
+  }
+  else {
+    my $rel_info = $self->relationship_info( $pre );
+    croak( $self->name . " has no such relationship '$pre'" ) unless $rel_info;
+    my $prefix = $alias && $alias ne 'me' ? "$alias.$pre" : $pre;
+    my @ret = map { "$prefix.$_" } $self->related_source($pre)->columns;
+    #warn $alias, Dumper (\@ret);
+    return @ret;
+  }
+}
 
 =head2 related_source($relname)
 
@@ -414,6 +489,9 @@ Returns the result source for the given relationship
 
 sub related_source {
   my ($self, $rel) = @_;
+  if( !$self->has_relationship( $rel ) ) {
+    croak "No such relationship '$rel'";
+  }
   return $self->schema->source($self->relationship_info($rel)->{source});
 }