like the rest of DBIC
- DBIC::FilterColumn "from_storage" handler is now invoked on NULLs
returned from storage
+ - find() now throws an exception if some of the supplied values are
+ managed by DBIC::FilterColumn (RT#95054)
- Custom condition relationships are now invoked with a slightly
different signature (existing coderefs will continue to work)
- Add extra custom condition coderef attribute 'foreign_values'
# relationship
}
else {
- my (@unique_queries, %seen_column_combinations);
+ my (@unique_queries, %seen_column_combinations, $ci, @fc_exceptions);
# no key was specified - fall down to heuristics mode:
# run through all unique queries registered on the resultset, and
join "\x00", sort $rsrc->unique_constraint_columns($c_name)
}++;
- push @unique_queries, try {
- $self->result_source->_minimal_valueset_satisfying_constraint(
- constraint_name => $c_name,
- values => ($self->_merge_with_rscond($call_cond))[0],
- ),
- } || ();
+ try {
+ push @unique_queries, $self->_qualify_cond_columns(
+ $self->result_source->_minimal_valueset_satisfying_constraint(
+ constraint_name => $c_name,
+ values => ($self->_merge_with_rscond($call_cond))[0],
+ columns_info => ($ci ||= $self->result_source->columns_info),
+ ),
+ $alias
+ );
+ }
+ catch {
+ push @fc_exceptions, $_ if $_ =~ /\bFilterColumn\b/;
+ };
}
- $final_cond = @unique_queries
- ? [ map { $self->_qualify_cond_columns($_, $alias) } @unique_queries ]
- : $self->_non_unique_find_fallback ($call_cond, $attrs)
+ $final_cond =
+ @unique_queries ? \@unique_queries
+ : @fc_exceptions ? $self->throw_exception(join "; ", map { $_ =~ /(.*) at .+ line \d+$/s } @fc_exceptions )
+ : $self->_non_unique_find_fallback ($call_cond, $attrs)
;
}
my $self = shift;
my $args = { ref $_[0] eq 'HASH' ? %{ $_[0] } : @_ };
+ $args->{columns_info} ||= $self->columns_info;
+
my $vals = $self->storage->_extract_fixed_condition_columns(
$args->{values},
($args->{carp_on_nulls} ? 'consider_nulls' : undef ),
else {
$cols->{present}{$col} = 1;
}
+
+ $cols->{fc}{$col} = 1 if (
+ ! ( $cols->{missing} || {})->{$col}
+ and
+ $args->{columns_info}{$col}{_filter_info}
+ );
}
$self->throw_exception( sprintf ( "Unable to satisfy requested constraint '%s', missing values for column(s): %s",
join (', ', map { "'$_'" } sort keys %{$cols->{missing}} ),
) ) if $cols->{missing};
+ $self->throw_exception( sprintf (
+ "Unable to satisfy requested constraint '%s', FilterColumn values not usable for column(s): %s",
+ $args->{constraint_name},
+ join (', ', map { "'$_'" } sort keys %{$cols->{fc}}),
+ )) if $cols->{fc};
+
if (
$cols->{undefined}
and
'Correctly throws exception for empty attributes'
;
+FC_ON_PK_TEST: {
+
+ DBICTest::Schema::Artist->filter_column(artistid => {
+ filter_to_storage => sub { $_[1] * 100 },
+ filter_from_storage => sub { $_[1] - 100 },
+ });
+
+ for my $key ('', 'primary') {
+ throws_ok {
+ $schema->resultset('Artist')->find_or_create({ artistid => 42 }, { $key ? ( key => $key ) : () });
+ } qr/\QUnable to satisfy requested constraint 'primary', FilterColumn values not usable for column(s): 'artistid'/;
+ }
+}
+
done_testing;