diff --git a/lib/Catalyst/Controller/DBIC/API/RequestArguments.pm b/lib/Catalyst/Controller/DBIC/API/RequestArguments.pm
index 107dc80..b899e77 100644
--- a/lib/Catalyst/Controller/DBIC/API/RequestArguments.pm
+++ b/lib/Catalyst/Controller/DBIC/API/RequestArguments.pm
@@ -477,6 +477,37 @@ JoinBuilder each layer of recursion.
# might be a sql function instead of a column name
# e.g. {colname => {like => '%foo%'}}
+ elsif ( $column eq '-or' or $column eq '-and' ) {
+ my $i = 0;
+ my $v = $param->{$column};
+
+ while (@$v > $i) {
+ if (not ref $v->[$i]) {
+ push @{$search_params->{$column}},
+ $self->generate_column_parameters(
+ $source,
+ { $v->[$i] => $v->[++$i] },
+ $join,
+ $base,
+ );
+ }
+ elsif (HashRef->check($v->[$i])) {
+ while ( my ( $k2, $v2 ) = each %{$v->[$i]} ) {
+ push @{$search_params->{$column}},
+ $self->generate_column_parameters(
+ $source,
+ { $k2 => $v2 },
+ $join,
+ $base,
+ );
+ }
+ }
+ else {
+ die "aa";
+ }
+ ++$i;
+ }
+ }
else {
# but only if it's not a hashref
unless ( ref( $param->{$column} )
diff --git a/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm b/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm
index 7631654..aab5232 100644
--- a/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm
+++ b/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm
@@ -110,7 +110,27 @@ sub check_column_relation {
if ( HashRef->check($col_rel) ) {
try {
while ( my ( $k, $v ) = each %$col_rel ) {
- $self->check_has_relation( $k, $v, undef, $static );
+ if ($k eq '-or' or $k eq '-and') {
+ die unless ArrayRef->check($v);
+ my $i = 0;
+ while (@$v > $i) {
+ if (not ref $v->[$i]) {
+ $self->check_column_relation( { $v->[$i] => $v->[++$i] } );
+ }
+ elsif (HashRef->check($v->[$i])) {
+ while ( my ( $k2, $v2 ) = each %{$v->[$i]} ) {
+ $self->check_column_relation( { $k2 => $v2 } );
+ }
+ }
+ else {
+ die;
+ }
+ ++$i;
+ }
+ }
+ else {
+ $self->check_has_relation( $k, $v, undef, $static );
+ }
}
}
catch {
diff --git a/t/rest/list.t b/t/rest/list.t
index a7a6eb6..747948b 100644
--- a/t/rest/list.t
+++ b/t/rest/list.t
@@ -210,6 +210,129 @@ my $track_list_url = "$base/api/rest/track";
);
}
+# -and|-or condition
+{
+ my @or_variants = (
+ # -or
+ [
+ search => {
+ title => [qw(Yowlin Howlin)],
+ },
+ ],
+ [
+ search => {
+ -or => [
+ title => [qw(Yowlin Howlin)],
+ ],
+ },
+ ],
+ [
+ search => {
+ -or => [
+ title => [qw(Yowlin)],
+ title => [qw(Howlin)],
+ ],
+ },
+ ],
+ [
+ search => {
+ -or => [
+ { title => [qw(Yowlin)] },
+ { title => [qw(Howlin)] },
+ ],
+ },
+ ],
+ # -and
+ [
+ search => {
+ cd => 2,
+ position => [1, 2],
+ },
+ ],
+ [
+ search => {
+ -and => [
+ cd => 2,
+ position => [1, 2],
+ ],
+ },
+ ],
+ # -and & -or
+ [
+ search => {
+ -or => [
+ -and => [
+ cd => 2,
+ position => [0, 1],
+ ],
+ -and => [
+ cd => 2,
+ position => [0, 2],
+ ],
+ ],
+ },
+ ],
+ [
+ search => {
+ -or => [
+ {
+ -and => [
+ cd => 2,
+ position => [0, 1],
+ ],
+ },
+ {
+ -and => [
+ cd => 2,
+ position => [0, 2],
+ ],
+ },
+ ],
+ },
+ ],
+ [
+ search => {
+ -or => [
+ {
+ -and => [
+ cd => 2,
+ position => [0, 1],
+ ],
+ },
+ {
+ -and => [
+ cd => 2,
+ position => [0, 2],
+ ],
+ },
+ ],
+ },
+ ],
+ );
+
+ for (@or_variants) {
+ my %q = (@$_);
+
+ is $schema->resultset('Track')->search($q{search})->count, 2, 'check -and|-or search param correctness';
+
+ my $uri = URI->new($track_list_url);
+ $uri->query_form( map { $_ => encode_json($q{$_}) } keys %q );
+ my $req = GET( $uri, 'Accept' => 'text/x-json' );
+ $mech->request($req);
+ cmp_ok( $mech->status, '==', 200, 'attempt with -or search okay' );
+ my $response = $json->decode( $mech->content );
+ my @expected_response = map {
+ { $_->get_columns }
+ } $schema->resultset('Track')->search($q{search})->all;
+ is_deeply(
+ $response,
+ # track does set use_json_boolean
+ { list => \@expected_response, success => JSON::true, totalcount => 2 },
+ 'correct data returned for -and|-or search param'
+ ) or diag Dumper \%q;
+ }
+}
+
{
my $uri = URI->new($artist_list_url);
$uri->query_form( { 'search.cds.track.title' => 'Suicidal' } );