);
my %methods = (
- lt => sub { +{ lt => $_[0] } },
- gt => sub { +{ gt => $_[0] } },
- ilike => sub { +{ ilike => $_[0] } },
- like => sub { +{ like => $_[0] } },
enable => sub { ;;;; },
+ map {
+ # since $_ is an alias it can't be used in a closure. even "".$_ or "$_"
+ # does not work, we need a real copy.
+ my $_copy = "$_";
+ $_ => sub { +{ $_copy => $_[0] } },
+ } qw(similar match imatch regex regexp like ilike rlike is is_not ne eq lt gt le ge),
);
sub parse_filter {
if ('HASH' eq ref $value) {
my ($query, $more_objects) = _pre_parse($value, $with_objects, _prefix($prefix, $key));
push @result, @$query if $query;
- push @$with_objects, $key, ($more_objects ? @$more_objects : ());
+ push @$with_objects, _prefix($prefix, $key), ($more_objects ? @$more_objects : ());
} else {
push @result, _prefix($prefix, $key) => $value;
}
return () unless 'ARRAY' eq ref $flattened;
- my %sorted = ( @$flattened );
+ $flattened = _collapse_indirect_filters($flattened);
+
+ my @result;
+ for (my $i = 0; $i < scalar @$flattened; $i += 2) {
+ my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
+ ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/, { %filters, %{ $params{filters} || {} } });
+ ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } });
+ push @result, $key, $value;
+ }
+ return \@result;
+}
+
+sub _collapse_indirect_filters {
+ my ($flattened) = @_;
+
+ die 'flattened filter array length is uneven, should be possible to use as hash' if @$flattened % 2;
+
+ my (%keys_to_delete, %keys_to_move, @collapsed);
+
+ # search keys matching /::$/;
+ for (my $i = 0; $i < scalar @$flattened; $i += 2) {
+ my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
- my @keys = sort { length($b) <=> length($a) } keys %sorted;
- for my $key (@keys) {
next unless $key =~ /^(.*\b)::$/;
- $sorted{$1 . '::' . delete $sorted{$key} } = delete $sorted{$1} if $sorted{$1} && $sorted{$key};
+
+ $keys_to_delete{$key}++;
+ $keys_to_move{$1} = $1 . '::' . $value;
}
- my %result;
- while (my ($key, $value) = each %sorted) {
- ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/, { %filters, %{ $params{filters} || {} } });
- ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } });
- $result{$key} = $value;
+ for (my $i = 0; $i < scalar @$flattened; $i += 2) {
+ my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
+
+ if ($keys_to_move{$key}) {
+ push @collapsed, $keys_to_move{$key}, $value;
+ next;
+ }
+ if (!$keys_to_delete{$key}) {
+ push @collapsed, $key, $value;
+ }
}
- return [ %result ];
+
+ return \@collapsed;
}
sub _prefix {