From: Matt S Trout Date: Fri, 30 Dec 2005 01:26:08 +0000 (+0000) Subject: Moved inflation to inflate_result in Row.pm X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b52e9bf8ba1cd1fb4aa707615a6b2564de04cb8a;p=dbsrgits%2FDBIx-Class-Historic.git Moved inflation to inflate_result in Row.pm --- diff --git a/lib/DBIx/Class/CDBICompat/ImaDBI.pm b/lib/DBIx/Class/CDBICompat/ImaDBI.pm index 8cb7c48..aff3713 100644 --- a/lib/DBIx/Class/CDBICompat/ImaDBI.pm +++ b/lib/DBIx/Class/CDBICompat/ImaDBI.pm @@ -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; } diff --git a/lib/DBIx/Class/CDBICompat/LiveObjectIndex.pm b/lib/DBIx/Class/CDBICompat/LiveObjectIndex.pm index 7d04710..6c9602b 100644 --- a/lib/DBIx/Class/CDBICompat/LiveObjectIndex.pm +++ b/lib/DBIx/Class/CDBICompat/LiveObjectIndex.pm @@ -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) { diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index ba44f0f..0986be8 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -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 diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index e52e179..88188e9 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -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; diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 2354a7a..7edda48 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -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; }