{{ $NEXT }}
- Fix links to ::Request::Context
+ - Add support for the -and, -not and -or operators (RT93864)
2.005001 2014-01-13 21:43:59+01:00 Europe/Vienna
- Fixed test failures with JSON 2.90 (RT#90188, thanks Samuel Kaufman!)
For more information, please see L<Data::DPath::Validator> and more specifically
L<Catalyst::Controller::DBIC::API::Validator>.
-Since 2.00100:
+Since 2.001:
Transactions are used. The stash is put aside in favor of roles applied to the
request object with additional accessors.
Error handling is now much more consistent with most errors immediately detaching.
The internals are much easier to read and understand with lots more documentation.
+Since 2.006:
+The SQL::Abstract -and, -not and -or operators are supported.
+
=cut
1;
$base ||= 'me';
my $search_params = {};
+ # return non-hashref params unaltered
+ return $param
+ unless ref $param eq 'HASH';
+
# build up condition
foreach my $column ( keys %$param ) {
+ my $value = $param->{$column};
if ( $source->has_relationship($column) ) {
# check if the value isn't a hashref
- unless ( ref( $param->{$column} )
- && reftype( $param->{$column} ) eq 'HASH' )
+ unless ( ref $value eq 'HASH' )
{
$search_params->{ join( '.', $base, $column ) } =
- $param->{$column};
+ $value;
next;
}
%$search_params,
%{ $self->generate_column_parameters(
$source->related_source($column),
- $param->{$column},
+ $value,
Catalyst::Controller::DBIC::API::JoinBuilder->new(
parent => $join,
name => $column
$search_params->{ join( '.', $base, $column ) } =
$param->{$column};
}
+ elsif ( $column eq '-or' || $column eq '-and' || $column eq '-not' ) {
+ # either an arrayref or hashref
+ if ( ref $value eq 'HASH' ) {
+ $search_params->{$column} = $self->generate_column_parameters(
+ $source,
+ $value,
+ $join,
+ $base,
+ );
+ }
+ elsif ( ref $value eq 'ARRAY' ) {
+ push @{$search_params->{$column}},
+ $self->generate_column_parameters(
+ $source,
+ $_,
+ $join,
+ $base,
+ )
+ for @$value;
+ }
+ else {
+ die "unsupported value '$value' for column '$column'\n";
+ }
+ }
# might be a sql function instead of a column name
# e.g. {colname => {like => '%foo%'}}
else {
# but only if it's not a hashref
- unless ( ref( $param->{$column} )
- && reftype( $param->{$column} ) eq 'HASH' )
- {
+ unless ( ref $value eq 'HASH' ) {
$search_params->{ join( '.', $base, $column ) } =
$param->{$column};
}
else {
- die "$column is neither a relationship nor a column\n";
+ die "unsupported value '$value' for column '$column'\n";
}
}
}
use Test::WWW::Mechanize::Catalyst 'RestTest';
use HTTP::Request::Common;
use JSON;
+use Data::Printer;
my $json = JSON->new->utf8;
);
}
+# -and|-or condition
+{
+ my @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 my $case ( @variants ) {
+ is $schema->resultset('Track')->search($case->{search})->count, 2, 'check -and|-or search param correctness';
+
+ my $uri = URI->new($track_list_url);
+ $uri->query_form( map { $_ => encode_json($case->{$_}) } keys %$case );
+ 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($case->{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 p($case) . p($response);
+ }
+}
+
{
my $uri = URI->new($artist_list_url);
$uri->query_form( { 'search.cds.track.title' => 'Suicidal' } );
cmp_ok( $mech->status, '==', 400,
'attempt with nonexisting relationship fails' );
my $response = $json->decode( $mech->content );
- is_deeply(
- $response->{messages},
- ['track is neither a relationship nor a column'],
+ like(
+ $response->{messages}->[0],
+ qr/unsupported value 'HASH\([^\)]+\)' for column 'track'/,
'correct error message returned'
);
}