my %rels = %{ $self->_relationships };
$rels{$rel} = { class => $f_source_name,
source => $f_source_name,
+ _original_name => $rel,
cond => $cond,
attrs => $attrs };
$self->_relationships(\%rels);
my $cols;
for my $col ($self->unique_constraint_columns($args->{constraint_name}) ) {
- if( ! exists $vals->{$col} ) {
- $cols->{missing}{$col} = 1;
+ if( ! exists $vals->{$col} or ( $vals->{$col}||'' ) eq UNRESOLVABLE_CONDITION ) {
+ $cols->{missing}{$col} = undef;
}
elsif( ! defined $vals->{$col} ) {
- $cols->{$args->{carp_on_nulls} ? 'undefined' : 'missing'}{$col} = 1;
+ $cols->{$args->{carp_on_nulls} ? 'undefined' : 'missing'}{$col} = undef;
}
else {
- $cols->{present}{$col} = 1;
+ # we need to inject back the '=' as _extract_fixed_condition_columns
+ # will strip it from literals and values alike, resulting in an invalid
+ # condition in the end
+ $cols->{present}{$col} = { '=' => $vals->{$col} };
}
$cols->{fc}{$col} = 1 if (
- ! ( $cols->{missing} || {})->{$col}
+ ( ! $cols->{missing} or ! exists $cols->{missing}{$col} )
and
- $args->{columns_info}{$col}{_filter_info}
+ keys %{ $args->{columns_info}{$col}{_filter_info} || {} }
);
}
));
}
- return { map
- { $_ => $vals->{$_} }
- ( keys %{$cols->{present}}, keys %{$cols->{undefined}} )
- };
+ return { map { %{ $cols->{$_}||{} } } qw(present undefined) };
}
# Returns the {from} structure used to express JOIN conditions
## self-explanatory API, modeled on the custom cond coderef:
# rel_name => (scalar)
# foreign_alias => (scalar)
-# foreign_values => (either not supplied or a hashref)
+# foreign_values => (either not supplied, or a hashref, or a foreign ResultObject (to be ->get_columns()ed), or plain undef )
# 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)
$self->throw_exception("Arguments 'self_alias' and 'foreign_alias' may not be identical")
if $args->{self_alias} eq $args->{foreign_alias};
- my $exception_rel_id = "relationship '$args->{rel_name}' on source '@{[ $self->source_name ]}'";
-
my $rel_info = $self->relationship_info($args->{rel_name})
# TEMP
# or $self->throw_exception( "No such $exception_rel_id" );
- or carp_unique("Requesting resolution on non-existent $exception_rel_id: fix your code *soon*, as it will break with the next major version");
+ or carp_unique("Requesting resolution on non-existent relationship '$args->{rel_name}' on source '@{[ $self->source_name ]}': fix your code *soon*, as it will break with the next major version");
+
+ my $exception_rel_id = "relationship '$rel_info->{_original_name}' on source '@{[ $self->source_name ]}'";
$self->throw_exception("No practical way to resolve $exception_rel_id between two data structures")
if exists $args->{self_result_object} and exists $args->{foreign_values};
$args->{condition} ||= $rel_info->{cond};
-# TEMP
-# my $rel_rsrc = $self->related_source($args->{rel_name});
-
- if (exists $args->{self_result_object}) {
- $self->throw_exception( "Argument 'self_result_object' must be an object of class '@{[ $self->result_class ]}'" )
- unless defined blessed $args->{self_result_object};
+ $self->throw_exception( "Argument 'self_result_object' must be an object of class '@{[ $self->result_class ]}'" )
+ if (
+ exists $args->{self_result_object}
+ and
+ ( ! defined blessed $args->{self_result_object} or ! $args->{self_result_object}->isa($self->result_class) )
+ )
+ ;
- $self->throw_exception( "Object '$args->{self_result_object}' must be of class '@{[ $self->result_class ]}'" )
- unless $args->{self_result_object}->isa($self->result_class);
- }
+ my $rel_rsrc = $self->related_source($args->{rel_name});
if (exists $args->{foreign_values}) {
if (defined blessed $args->{foreign_values}) {
- $self->throw_exception( "Object supplied as 'foreign_values' ($args->{foreign_values}) must be of class '$rel_info->{class}'" )
- unless $args->{foreign_values}->isa($rel_info->{class});
+
+ $self->throw_exception( "Objects supplied as 'foreign_values' ($args->{foreign_values}) must inherit from DBIx::Class::Row" )
+ unless $args->{foreign_values}->isa('DBIx::Class::Row');
+
+ 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 (! defined $args->{foreign_values} or ref $args->{foreign_values} eq 'HASH') {
- # TEMP
- my $rel_rsrc = $self->related_source($args->{rel_name});
my $ci = $rel_rsrc->columns_info;
! exists $ci->{$_} and $self->throw_exception(
"Key '$_' supplied as 'foreign_values' is not a column on related source '@{[ $rel_rsrc->source_name ]}'"
) for keys %{ $args->{foreign_values} ||= {} };
}
else {
- $self->throw_exception( "Argument 'foreign_values' must be either an object inheriting from '$rel_info->{class}' or a hash reference or undef" );
+ $self->throw_exception(
+ "Argument 'foreign_values' must be either an object inheriting from '@{[ $rel_rsrc->result_class ]}', "
+ . "or a hash reference, or undef"
+ );
}
}
my ($joinfree_alias, $joinfree_source);
if (defined $args->{self_result_object}) {
- # TEMP
- my $rel_rsrc = $self->related_source($args->{rel_name});
$joinfree_alias = $args->{foreign_alias};
$joinfree_source = $rel_rsrc;
}
# there is no way to know who is right and who is left in a cref
# therefore a full blown resolution call
- # TEMP
- my $rel_rsrc = $self->related_source($args->{rel_name});
$colinfos ||= $storage->_resolve_column_info([
{ -alias => $args->{self_alias}, -rsrc => $self },
{ -alias => $args->{foreign_alias}, -rsrc => $rel_rsrc },