From: Matt S Trout Date: Sat, 14 Jan 2006 06:17:04 +0000 (+0000) Subject: resolve_condition moved to ResultSource X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=3842b955be8f0d2e424d60c46afc3bc37ac33b97;p=dbsrgits%2FDBIx-Class-Historic.git resolve_condition moved to ResultSource --- diff --git a/lib/DBIx/Class/CDBICompat/ImaDBI.pm b/lib/DBIx/Class/CDBICompat/ImaDBI.pm index 2226ea7..4651263 100644 --- a/lib/DBIx/Class/CDBICompat/ImaDBI.pm +++ b/lib/DBIx/Class/CDBICompat/ImaDBI.pm @@ -43,13 +43,9 @@ __PACKAGE__->mk_classdata('_transform_sql_handlers' => } $self->throw( "No relationship to JOIN from ${from_class} to ${to_class}" ) unless $rel_obj; - my $attrs = { - %$self, - _aliases => { self => $from, foreign => $to }, - _action => 'join', - }; my $join = $from_class->storage->sql_maker->_join_condition( - $from_class->resolve_condition($rel_obj->{cond}, $attrs) ); + $from_class->result_source->resolve_condition( + $rel_obj->{cond}, $to, $from) ); return $join; } diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index 35f9067..24c766d 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -83,81 +83,6 @@ sub relationship_info { shift->result_source->relationship_info(@_); } -sub resolve_condition { - my ($self, $cond, $attrs) = @_; - if (ref $cond eq 'HASH') { - my %ret; - foreach my $key (keys %$cond) { - my $val = $cond->{$key}; - if (ref $val) { - $self->throw("Can't handle this yet :("); - } else { - $ret{$self->_cond_key($attrs => $key)} - = $self->_cond_value($attrs => $key => $val); - } - } - return \%ret; - } else { - $self->throw("Can't handle this yet :("); - } -} - -sub _cond_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}"); - } - 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); - if (my $alias = $attrs->{_aliases}{$type}) { - my $class = $attrs->{_classes}{$alias}; - $self->throw("Unknown column $field on $class as $alias") - unless $class->has_column($field); - return join('.', $alias, $field); - } else { - $self->throw( "Unable to resolve type ${type}: only have aliases for ". - join(', ', keys %{$attrs->{_aliases} || {}}) ); - } - } - return $self->next::method($attrs, $key); -} - -sub _cond_value { - my ($self, $attrs, $key, $value) = @_; - my $action = $attrs->{_action} || ''; - if ($action eq 'convert') { - unless ($value =~ s/^self\.//) { - $self->throw( "Unable to convert relationship to WHERE clause: invalid value ${value}" ); - } - unless ($self->has_column($value)) { - $self->throw( "Unable to convert relationship to WHERE clause: no such accessor ${value}" ); - } - return $self->get_column($value); - } elsif ($action eq 'join') { - return $key unless $key =~ /\./; - my ($type, $field) = split(/\./, $value); - if (my $alias = $attrs->{_aliases}{$type}) { - my $class = $attrs->{_classes}{$alias}; - $self->throw("Unknown column $field on $class as $alias") - unless $class->has_column($field); - return join('.', $alias, $field); - } else { - $self->throw( "Unable to resolve type ${type}: only have aliases for ". - join(', ', keys %{$attrs->{_aliases} || {}}) ); - } - } - - return $self->next::method($attrs, $key, $value) -} - =head2 search_related My::Table->search_related('relname', $cond, $attrs); @@ -166,6 +91,7 @@ sub _cond_value { sub search_related { my $self = shift; + die "Can't call *_related as class methods" unless ref $self; my $rel = shift; my $attrs = { }; if (@_ > 1 && ref $_[$#_] eq 'HASH') { @@ -178,15 +104,12 @@ sub search_related { $self->throw( "Invalid query: @_" ) if (@_ > 1 && (@_ % 2 == 1)); my $query = ((@_ > 1) ? {@_} : shift); - $attrs->{_action} = 'convert'; # shouldn't we resolve the cond to something - # to merge into the AST really? - my ($cond) = $self->resolve_condition($rel_obj->{cond}, $attrs); + my ($cond) = $self->result_source->resolve_condition($rel_obj->{cond}, $rel, $self); $query = ($query ? { '-and' => [ $cond, $query ] } : $cond); - #use Data::Dumper; warn Dumper($query); + #use Data::Dumper; warn Dumper($cond); #warn $rel_obj->{class}." $meth $cond ".join(', ', @{$attrs->{bind}||[]}); - delete $attrs->{_action}; - return $self->result_source->schema->resultset($rel_obj->{class} - )->search($query, $attrs); + return $self->result_source->related_source($rel + )->resultset->search($query, $attrs); } =head2 count_related @@ -207,9 +130,9 @@ sub count_related { =cut sub create_related { - my $class = shift; + my $self = shift; my $rel = shift; - return $class->search_related($rel)->create(@_); + return $self->search_related($rel)->create(@_); } =head2 new_related diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index ec54d97..384e269 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -79,8 +79,8 @@ sub resultset { return $self->resultset_class->new($self); } -=head2 has_column - +=head2 has_column + if ($obj->has_column($col)) { ... } Returns 1 if the source has a column of this name, 0 otherwise. @@ -317,38 +317,39 @@ sub resolve_join { } elsif (ref $join) { die("No idea how to resolve join reftype ".ref $join); } else { - die("No such relationship ${join}") unless $self->has_relationship($join); - my $type = $self->relationship_info($join)->{attrs}{join_type} || ''; + my $rel_info = $self->relationship_info($join); + die("No such relationship ${join}") unless $rel_info; + my $type = $rel_info->{attrs}{join_type} || ''; return [ { $join => $self->related_source($join)->from, -join_type => $type }, - $self->resolve_condition($join, $alias) ]; + $self->resolve_condition($rel_info->{cond}, $join, $alias) ]; } } -=head2 resolve_condition($rel, $alias|$object) +=head2 resolve_condition($cond, $rel, $alias|$object) -Returns the conditional for the specified relationship. If given an alias, +Resolves the passed condition to a concrete query fragment. If given an alias, returns a join condition; if given an object, inverts that object to produce a related conditional from that object. =cut sub resolve_condition { - my ($self, $rel, $for) = @_; - my $cond = $self->relationship_info($rel)->{cond}; + my ($self, $cond, $rel, $for) = @_; #warn %$cond; if (ref $cond eq 'HASH') { my %ret; while (my ($k, $v) = each %{$cond}) { # XXX should probably check these are valid columns - $k =~ s/^foreign\./${rel}./ || die "Invalid rel cond key ${k}"; + $k =~ s/^foreign\.// || die "Invalid rel cond key ${k}"; + $v =~ s/^self\.// || die "Invalid rel cond val ${v}"; if (ref $for) { # Object - die "Invalid ref cond val ${v}" unless $v =~ m/^self\.(.*)$/; - $ret{$k} = $for->$1; + #warn "$self $k $for $v"; + $ret{$k} = $for->get_column($v); + #warn %ret; } else { - $v =~ s/^self\./${for}./ || die "Invalid rel cond val ${v}"; + $ret{"${rel}.${k}"} = "${for}.${v}"; } - $ret{$k} = $v; } return \%ret; } else {