use Data::Dumper;
use Text::ParseWords;
+sub _lazy_bool_eq {
+ my ($key, $value) = @_;
+
+ return () if ($value // '') eq '';
+ return (or => [ $key => undef, $key => 0 ]) if !$value;
+ return ($key => 1);
+}
+
my %filters = (
date => sub { DateTime->from_lxoffice($_[0]) },
number => sub { $::form->parse_amount(\%::myconfig, $_[0]) },
} qw(similar match imatch regex regexp like ilike rlike is is_not ne eq lt gt le ge),
);
+my %complex_methods = (
+ lazy_bool_eq => \&_lazy_bool_eq,
+);
+
sub parse_filter {
my ($filter, %params) = @_;
$flattened = _collapse_indirect_filters($flattened);
- my $all_filters = { %filters, %{ $params{filters} || {} } };
- my $all_methods = { %methods, %{ $params{methods} || {} } };
+ my $all_filters = { %filters, %{ $params{filters} || {} } };
+ my $all_methods = { %methods, %{ $params{methods} || {} } };
+ my $all_complex = { %complex_methods, %{ $params{complex_methods} || {} } };
my @result;
for (my $i = 0; $i < scalar @$flattened; $i += 2) {
- my (@args, @filters, @methods);
+ my (@args, @filters, $method);
my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
my ($type, $op) = $key =~ m{:(.+)::(.+)};
my $is_multi = $key =~ s/:multi//;
my @value_tokens = $is_multi ? parse_line('\s+', 0, $value) : ($value);
- ($key, @methods) = split m{::}, $key;
+ ($key, $method) = split m{::}, $key, 2;
($key, @filters) = split m{:}, $key;
my $orig_key = $key;
$key = $orig_key;
$value_token = _apply($value_token, $_, $all_filters) for @filters;
- $value_token = _apply($value_token, $_, $all_methods) for @methods;
+ $value_token = _apply($value_token, $method, $all_methods) if $method && exists $all_methods->{$method};
+ ($key, $value_token) = _apply_complex($key, $value_token, $method, $all_complex) if $method && exists $all_complex->{$method};
($key, $value_token) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value_token) if $params{class};
($key, $value_token) = _apply_value_filters($key, $value_token, $type, $op);
return $filters->{$name}->($value);
}
+sub _apply_complex {
+ my ($key, $value, $name, $filters) = @_;
+ return $key, $value unless $name && $filters->{$name};
+ return $filters->{$name}->($key, $value);
+}
+
1;
__END__
All these are recognized like the L<Rose::DB::Object> methods.
+=item lazu_bool_eq
+
+If the value is undefined or an empty string then this parameter will
+be completely removed from the query. Otherwise a falsish filter value
+will match for C<NULL> and C<FALSE>; trueish values will only match
+C<TRUE>.
+
=back
=head1 BUGS AND CAVEATS