X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=3b318a44b01daf13a94b009def6c90aeba851115;hb=d56c319181b46e4f80d301d27d2f80e49751b460;hp=cd819a891095f4098d3e9a1fe2422b972b8da93c;hpb=2e2512552309024151dc45c24b66032f510ca613;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index cd819a8..3b318a4 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -116,6 +116,18 @@ automatically set. This is used to determine which columns to empty when cloning objects using L. It is also used by L. +=item is_numeric + +Set this to a true or false value (not C) to explicitly specify +if this column contains numeric data. This controls how set_column +decides whether to consider a column dirty after an update: if +C is true a numeric comparison C<< != >> will take place +instead of the usual C + +If not specified the storage class will attempt to figure this out on +first access to the column, based on the column C. The +result will be cached in this attribute. + =item is_foreign_key Set this to a true value for a column that contains a key from a @@ -881,7 +893,7 @@ sub add_relationship { } return unless $f_source; # Can't test rel without f_source - eval { $self->_resolve_join($rel, 'me') }; + eval { $self->_resolve_join($rel, 'me', {}, []) }; if ($@) { # If the resolve failed, back out and re-throw the error delete $rels{$rel}; # @@ -1071,26 +1083,21 @@ sub resolve_join { # Returns the {from} structure used to express JOIN conditions sub _resolve_join { - my ($self, $join, $alias, $seen, $force_left, $jpath) = @_; + my ($self, $join, $alias, $seen, $jpath, $force_left) = @_; # we need a supplied one, because we do in-place modifications, no returns $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join') - unless $seen; + unless ref $seen eq 'HASH'; - $force_left ||= { force => 0 }; + $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join') + unless ref $jpath eq 'ARRAY'; - # This isn't quite right, we should actually dive into $seen and reconstruct - # the entire path (the reference entry point would be the join conditional - # with depth == current_depth - 1. At this point however nothing depends on - # having the entire path, transcending related_resultset, so just leave it - # as is, hairy enough already. - $jpath ||= []; + $jpath = [@$jpath]; if (ref $join eq 'ARRAY') { return map { - local $force_left->{force} = $force_left->{force}; - $self->_resolve_join($_, $alias, $seen, $force_left, [@$jpath]); + $self->_resolve_join($_, $alias, $seen, $jpath, $force_left); } @$join; } elsif (ref $join eq 'HASH') { return @@ -1098,9 +1105,9 @@ sub _resolve_join { my $as = ($seen->{$_} ? join ('_', $_, $seen->{$_} + 1) : $_); # the actual seen value will be incremented below local $force_left->{force} = $force_left->{force}; ( - $self->_resolve_join($_, $alias, $seen, $force_left, [@$jpath]), + $self->_resolve_join($_, $alias, $seen, [@$jpath], $force_left), $self->related_source($_)->_resolve_join( - $join->{$_}, $as, $seen, $force_left, [@$jpath, $_] + $join->{$_}, $as, $seen, [@$jpath, $_], $force_left ) ); } keys %$join; @@ -1108,22 +1115,27 @@ sub _resolve_join { $self->throw_exception("No idea how to resolve join reftype ".ref $join); } else { + return() unless defined $join; + my $count = ++$seen->{$join}; my $as = ($count > 1 ? "${join}_${count}" : $join); my $rel_info = $self->relationship_info($join); $self->throw_exception("No such relationship ${join}") unless $rel_info; my $type; - if ($force_left->{force}) { + if ($force_left) { $type = 'left'; } else { $type = $rel_info->{attrs}{join_type} || ''; - $force_left->{force} = 1 if lc($type) eq 'left'; + $force_left = 1 if lc($type) eq 'left'; } - return [ { $as => $self->related_source($join)->from, + + my $rel_src = $self->related_source($join); + return [ { $as => $rel_src->from, + -source_handle => $rel_src->handle, -join_type => $type, -join_path => [@$jpath, $join], - -join_alias => $as, + -alias => $as, -relation_chain_depth => $seen->{-relation_chain_depth} || 0, }, $self->_resolve_condition($rel_info->{cond}, $as, $alias) ]; @@ -1181,7 +1193,6 @@ our $UNRESOLVABLE_CONDITION = \'1 = 0'; sub _resolve_condition { my ($self, $cond, $as, $for) = @_; - #warn %$cond; if (ref $cond eq 'HASH') { my %ret; foreach my $k (keys %{$cond}) { @@ -1222,7 +1233,7 @@ sub _resolve_condition { } elsif (ref $cond eq 'ARRAY') { return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ]; } else { - die("Can't handle this yet :("); + die("Can't handle condition $cond yet :("); } } @@ -1327,15 +1338,14 @@ sub _resolve_prefetch { "don't know how to resolve prefetch reftype ".ref($pre)); } else { - my $p = $alias_map; $p = $p->{$_} for (@$pref_path, $pre); $self->throw_exception ( - "Unable to resolve prefetch $pre - join alias map does not contain an entry for path " + "Unable to resolve prefetch $pre - join alias map does not contain an entry for path: " . join (' -> ', @$pref_path, $pre) ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} ); - + my $as = shift @{$p->{-join_aliases}}; my $rel_info = $self->relationship_info( $pre );