Moved inflation to inflate_result in Row.pm
Matt S Trout [Fri, 30 Dec 2005 01:26:08 +0000 (01:26 +0000)]
lib/DBIx/Class/CDBICompat/ImaDBI.pm
lib/DBIx/Class/CDBICompat/LiveObjectIndex.pm
lib/DBIx/Class/Relationship/Base.pm
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Row.pm

index 8cb7c48..aff3713 100644 (file)
@@ -91,10 +91,9 @@ sub set_sql {
 
 sub sth_to_objects {
   my ($class, $sth) = @_;
-  my @cols = $class->_select_columns;
   my @ret;
-  while (my @row = $sth->fetchrow_array) {
-    push(@ret, $class->_row_to_object(\@cols,\@row));
+  while (my $row = $sth->fetchrow_hashref) {
+    push(@ret, $class->inflate_result($row));
   }
   return @ret;
 }
index 7d04710..6c9602b 100644 (file)
@@ -51,7 +51,7 @@ sub insert {
   return $self;
 }
 
-sub _row_to_object {
+sub inflate_result {
   my ($class, @rest) = @_;
   my $new = $class->next::method(@rest);
   if (my $key = $new->ID) {
index ba44f0f..0986be8 100644 (file)
@@ -139,13 +139,17 @@ sub resolve_condition {
 }
 
 sub _cond_key {
-  my ($self, $attrs, $key) = @_;
+  my ($self, $attrs, $key, $alias) = @_;
   my $action = $attrs->{_action} || '';
   if ($action eq 'convert') {
     unless ($key =~ s/^foreign\.//) {
       $self->throw("Unable to convert relationship to WHERE clause: invalid key ${key}");
     }
-    return $key;
+    if (defined (my $alias = $attrs->{_aliases}{foreign})) {
+      return "${alias}.${key}";
+    } else {
+      return $key;
+    }
   } elsif ($action eq 'join') {
     return $key unless $key =~ /\./;
     my ($type, $field) = split(/\./, $key);
@@ -198,23 +202,6 @@ sub _cond_value {
 
 sub search_related {
   my $self = shift;
-  return $self->_query_related('search', @_);
-}
-
-=head2 count_related
-
-  My::Table->count_related('relname', $cond, $attrs);
-
-=cut
-
-sub count_related {
-  my $self = shift;
-  return $self->_query_related('count', @_);
-}
-
-sub _query_related {
-  my $self = shift;
-  my $meth = shift;
   my $rel = shift;
   my $attrs = { };
   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
@@ -235,7 +222,18 @@ sub _query_related {
   #warn $rel_obj->{class}." $meth $cond ".join(', ', @{$attrs->{bind}||[]});
   delete $attrs->{_action};
   return $self->resolve_class($rel_obj->{class}
-           )->$meth($query, $attrs);
+           )->search($query, $attrs);
+}
+
+=head2 count_related
+
+  My::Table->count_related('relname', $cond, $attrs);
+
+=cut
+
+sub count_related {
+  my $self = shift;
+  return $self->search_related(@_)->count;
 }
 
 =head2 create_related
index e52e179..88188e9 100644 (file)
@@ -47,19 +47,19 @@ sub new {
   $attrs->{as} ||= [ map { m/^me\.(.*)$/ ? $1 : $_ } @{$attrs->{select}} ];
   #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
   $attrs->{from} ||= [ { 'me' => $source->name } ];
-  if ($attrs->{join}) {
-    foreach my $j (ref $attrs->{join} eq 'ARRAY'
-              ? (@{$attrs->{join}}) : ($attrs->{join})) {
+  if (my $join = delete $attrs->{join}) {
+    foreach my $j (ref $join eq 'ARRAY'
+              ? (@{$join}) : ($join)) {
       if (ref $j eq 'HASH') {
         $seen{$_} = 1 foreach keys %$j;
       } else {
         $seen{$j} = 1;
       }
     }
-    push(@{$attrs->{from}}, $source->result_class->_resolve_join($attrs->{join}, 'me'));
+    push(@{$attrs->{from}}, $source->result_class->_resolve_join($join, 'me'));
   }
   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
-  foreach my $pre (@{$attrs->{prefetch} || []}) {
+  foreach my $pre (@{delete $attrs->{prefetch} || []}) {
     push(@{$attrs->{from}}, $source->result_class->_resolve_join($pre, 'me'))
       unless $seen{$pre};
     my @pre = 
@@ -131,6 +131,14 @@ sub search_literal {
   return $self->search(\$cond, $attrs);
 }
 
+=head2 search_related
+
+  $rs->search_related('relname', $cond?, $attrs?);
+
+=cut
+
+sub search_related { }
+
 =head2 cursor
 
 Returns a storage-driven cursor to the given resultset.
@@ -199,36 +207,15 @@ sub _construct_object {
   my ($self, @row) = @_;
   my @cols = @{ $self->{attrs}{as} };
   #warn "@cols -> @row";
-  @cols = grep { /\(/ or ! /\./ } @cols;
-  my $new;
-  unless ($self->{attrs}{prefetch}) {
-    $new = $self->{source}->result_class->_row_to_object(\@cols, \@row);
-  } else {
-    my @main = splice(@row, 0, scalar @cols);
-    $new = $self->{source}->result_class->_row_to_object(\@cols, \@main);
-    PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
-      my $rel_obj = $self->{source}->result_class->_relationships->{$pre};
-      my $pre_class = $self->{source}->result_class->resolve_class($rel_obj->{class});
-      my @pre_cols = $pre_class->_select_columns;
-      my @vals = splice(@row, 0, scalar @pre_cols);
-      my $fetched = $pre_class->_row_to_object(\@pre_cols, \@vals);
-      $self->{source}->result_class->throw("No accessor for prefetched $pre")
-        unless defined $rel_obj->{attrs}{accessor};
-      if ($rel_obj->{attrs}{accessor} eq 'single') {
-        foreach my $pri ($rel_obj->{class}->primary_columns) {
-          unless (defined $fetched->get_column($pri)) {
-            undef $fetched;
-            last;
-          }
-        }
-        $new->{_relationship_data}{$pre} = $fetched;
-      } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
-        $new->{_inflated_column}{$pre} = $fetched;
-      } else {
-        $self->{source}->result_class->throw("Don't know how to store prefetched $pre");
-      }
+  my (%me, %pre);
+  foreach my $col (@cols) {
+    if ($col =~ /([^\.]+)\.([^\.]+)/) {
+      $pre{$1}{$2} = shift @row;
+    } else {
+      $me{$col} = shift @row;
     }
   }
+  my $new = $self->{source}->result_class->inflate_result(\%me, \%pre);
   $new = $self->{attrs}{record_filter}->($new)
     if exists $self->{attrs}{record_filter};
   return $new;
index 2354a7a..7edda48 100644 (file)
@@ -243,12 +243,39 @@ sub store_column {
   return $self->{_column_data}{$column} = $value;
 }
 
-sub _row_to_object {
-  my ($class, $cols, $row) = @_;
-  my %vals;
-  $vals{$cols->[$_]} = $row->[$_] for 0 .. $#$cols;
-  my $new = bless({ _column_data => \%vals }, ref $class || $class);
+=head2 inflate_result
+
+  Class->inflate_result(\%me, \%prefetch?)
+
+Called by ResultSet to inflate a result from storage
+
+=cut
+
+sub inflate_result {
+  my ($class, $me, $prefetch) = @_;
+  #use Data::Dumper; print Dumper(@_);
+  my $new = bless({ _column_data => $me }, ref $class || $class);
   $new->in_storage(1);
+  PRE: foreach my $pre (keys %{$prefetch||{}}) {
+    my $rel_obj = $class->_relationships->{$pre};
+    my $pre_class = $class->resolve_class($rel_obj->{class});
+    my $fetched = $pre_class->inflate_result($prefetch->{$pre});
+    $class->throw("No accessor for prefetched $pre")
+      unless defined $rel_obj->{attrs}{accessor};
+    if ($rel_obj->{attrs}{accessor} eq 'single') {
+      PRIMARY: foreach my $pri ($rel_obj->{class}->primary_columns) {
+        unless (defined $fetched->get_column($pri)) {
+          undef $fetched;
+          last PRIMARY;
+        }
+      }
+      $new->{_relationship_data}{$pre} = $fetched;
+    } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
+      $new->{_inflated_column}{$pre} = $fetched;
+    } else {
+      $class->throw("Don't know how to store prefetched $pre");
+    }
+  }
   return $new;
 }