$is_objlike[$_] = 0;
$res_args[$_] = '__gremlins__';
}
+ # more compat
+ elsif( $_ == 0 and $res_args[0]->isa( $__expected_result_class_isa ) ) {
+ $res_args[0] = { $res_args[0]->get_columns };
+ }
}
else {
$res_args[$_] ||= {};
## self-explanatory API, modeled on the custom cond coderef:
# rel_name => (scalar)
# foreign_alias => (scalar)
-# foreign_values => (either not supplied, or a hashref, or a foreign ResultObject (to be ->get_columns()ed), or plain undef )
+# foreign_values => (either not supplied or a hashref )
# self_alias => (scalar)
# self_result_object => (either not supplied or a result object)
# require_join_free_condition => (boolean, throws on failure to construct a JF-cond)
my $rel_rsrc = $self->related_source($args->{rel_name});
- if (exists $args->{foreign_values}) {
-
- if (! defined $args->{foreign_values} ) {
- # fallback: undef => {}
- $args->{foreign_values} = {};
- }
- elsif (defined blessed $args->{foreign_values}) {
-
- $self->throw_exception( "Objects supplied as 'foreign_values' ($args->{foreign_values}) must inherit from '$__expected_result_class_isa'" )
- unless $args->{foreign_values}->isa( $__expected_result_class_isa );
-
- carp_unique(
- "Objects supplied as 'foreign_values' ($args->{foreign_values}) "
- . "usually should inherit from the related ResultClass ('@{[ $rel_rsrc->result_class ]}'), "
- . "perhaps you've made a mistake invoking the condition resolver?"
- ) unless $args->{foreign_values}->isa($rel_rsrc->result_class);
-
- $args->{foreign_values} = { $args->{foreign_values}->get_columns };
- }
- elsif ( ref $args->{foreign_values} eq 'HASH' ) {
-
- # re-build {foreign_values} excluding identically named rels
- if( keys %{$args->{foreign_values}} ) {
+ if (
+ exists $args->{foreign_values}
+ and
+ (
+ ref $args->{foreign_values} eq 'HASH'
+ or
+ $self->throw_exception(
+ "Argument 'foreign_values' must be a hash reference"
+ )
+ )
+ and
+ keys %{$args->{foreign_values}}
+ ) {
- my ($col_idx, $rel_idx) = map
- { { map { $_ => 1 } $rel_rsrc->$_ } }
- qw( columns relationships )
- ;
+ my ($col_idx, $rel_idx) = map
+ { { map { $_ => 1 } $rel_rsrc->$_ } }
+ qw( columns relationships )
+ ;
- my $equivalencies = extract_equality_conditions(
- $args->{foreign_values},
- 'consider nulls',
- );
+ my $equivalencies;
- $args->{foreign_values} = { map {
- # skip if relationship *and* a non-literal ref
- # this means a multicreate stub was passed in
+ # re-build {foreign_values} excluding refs as follows
+ # ( hot codepath: intentionally convoluted )
+ #
+ $args->{foreign_values} = { map {
+ (
+ $_ !~ /^-/
+ or
+ $self->throw_exception(
+ "The key '$_' supplied as part of 'foreign_values' during "
+ . 'relationship resolution must be a column name, not a function'
+ )
+ )
+ and
+ (
+ # skip if relationship ( means a multicreate stub was passed in )
+ # skip if literal ( can't infer anything about it )
+ # or plain throw if nonequiv yet not literal
+ (
+ length ref $args->{foreign_values}{$_}
+ and
(
$rel_idx->{$_}
- and
- length ref $args->{foreign_values}{$_}
- and
- ! is_literal_value($args->{foreign_values}{$_})
+ or
+ is_literal_value($args->{foreign_values}{$_})
+ or
+ (
+ (
+ ! exists(
+ ( $equivalencies ||= extract_equality_conditions( $args->{foreign_values}, 'consider nulls' ) )
+ ->{$_}
+ )
+ or
+ ($equivalencies->{$_}||'') eq UNRESOLVABLE_CONDITION
+ )
+ and
+ $self->throw_exception(
+ "Resolution of relationship '$args->{rel_name}' failed: "
+ . "supplied value for foreign column '$_' is not a direct "
+ . 'equivalence expression'
+ )
+ )
)
- ? ()
- : ( $_ => (
- ! $col_idx->{$_}
- ? $self->throw_exception( "Key '$_' supplied as 'foreign_values' is not a column on related source '@{[ $rel_rsrc->source_name ]}'" )
- : ( !exists $equivalencies->{$_} or ($equivalencies->{$_}||'') eq UNRESOLVABLE_CONDITION )
- ? $self->throw_exception( "Value supplied for '...{foreign_values}{$_}' is not a direct equivalence expression" )
- : $args->{foreign_values}{$_}
- ))
- } keys %{$args->{foreign_values}} };
- }
- }
- else {
- $self->throw_exception(
- "Argument 'foreign_values' must be either an object inheriting from '@{[ $rel_rsrc->result_class ]}', "
- . "or a hash reference, or undef"
- );
- }
+ ) ? ()
+ : $col_idx->{$_} ? ( $_ => $args->{foreign_values}{$_} )
+ : $self->throw_exception(
+ "The key '$_' supplied as part of 'foreign_values' during "
+ . 'relationship resolution is not a column on related source '
+ . "'@{[ $rel_rsrc->source_name ]}'"
+ )
+ )
+ } keys %{$args->{foreign_values}} };
}
my $ret;
$self->throw_exception("A custom condition coderef can return at most 2 conditions, but $exception_rel_id returned extra values: @extra")
if @extra;
- if (my $jfc = $ret->{join_free_condition}) {
+ if( $ret->{join_free_condition} ) {
$self->throw_exception (
"The join-free condition returned for $exception_rel_id must be a hash reference"
- ) unless ref $jfc eq 'HASH';
+ ) unless ref $ret->{join_free_condition} eq 'HASH';
my ($joinfree_alias, $joinfree_source);
if (defined $args->{self_result_object}) {
"The join-free condition returned for $exception_rel_id may only "
. 'contain keys that are fully qualified column names of the corresponding source '
. "'$joinfree_alias' (instead it returned '$_')"
- ) for keys %$jfc;
+ ) for keys %{$ret->{join_free_condition}};
(
defined blessed($_)
. 'contain result objects as values - perhaps instead of invoking '
. '->$something you meant to return ->get_column($something)'
)
- ) for values %$jfc;
+ ) for values %{$ret->{join_free_condition}};
}
}
# FIXME - temporarly force-override
delete $args->{require_join_free_condition};
- $ret->{join_free_condition} = UNRESOLVABLE_CONDITION;
+ delete $ret->{join_free_condition};
last;
}
}
if (@{ $rel_info->{cond} } == 0) {
$ret = {
condition => UNRESOLVABLE_CONDITION,
- join_free_condition => UNRESOLVABLE_CONDITION,
};
}
else {
if (
$args->{require_join_free_condition}
and
- ( ! $ret->{join_free_condition} or $ret->{join_free_condition} eq UNRESOLVABLE_CONDITION )
+ ! defined $ret->{join_free_condition}
) {
$self->throw_exception(
ucfirst sprintf "$exception_rel_id does not resolve to a %sjoin-free condition fragment",
# we got something back - sanity check and infer values if we can
my @nonvalues;
- if (
- $ret->{join_free_condition}
- and
- $ret->{join_free_condition} ne UNRESOLVABLE_CONDITION
- ) {
+ if( $ret->{join_free_condition} ) {
my $jfc_eqs = extract_equality_conditions(
$ret->{join_free_condition},
push @nonvalues, { $_ => $ret->{join_free_condition}{$_} };
}
else {
- # a join_free_condoition is fully qualified by definition
+ # a join_free_condition is fully qualified by definition
my ($col) = $_ =~ /\.(.+)/ or carp_unique(
'Internal error - extract_equality_conditions() returned a '
. "non-fully-qualified key '$_'. *Please* file a bugreport "