[Catalyst-commits] r10173 - in
Catalyst-Controller-DBIC-API/1.003/trunk: .
lib/Catalyst/Controller/DBIC lib/Catalyst/Controller/DBIC/API
t/lib/RestTest/Controller/API/REST
t/lib/RestTest/Controller/API/RPC t/rpc
lukes at dev.catalyst.perl.org
lukes at dev.catalyst.perl.org
Sat May 16 11:51:55 GMT 2009
Author: lukes
Date: 2009-05-16 11:51:55 +0000 (Sat, 16 May 2009)
New Revision: 10173
Modified:
Catalyst-Controller-DBIC-API/1.003/trunk/Changes
Catalyst-Controller-DBIC-API/1.003/trunk/Makefile.PL
Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API.pm
Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/Base.pm
Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/REST.pm
Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/RPC.pm
Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm
Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm
Catalyst-Controller-DBIC-API/1.003/trunk/t/rpc/list.t
Log:
manually merged prefetch branch
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/Changes
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/Changes 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/Changes 2009-05-16 11:51:55 UTC (rev 10173)
@@ -1,7 +1,7 @@
Revision history for Catalyst-Controller-DBIC-API
-1.002001
-- Minor change to make this module work with Catalyst::Runtime 5.80
+1.003000
+- Added prefetch support
1.002000
- Better error handing when unable to parse search arg
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/Makefile.PL
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/Makefile.PL 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/Makefile.PL 2009-05-16 11:51:55 UTC (rev 10173)
@@ -9,6 +9,7 @@
requires 'Catalyst::Action::REST' => 0.60;
requires 'CGI::Expand' => 2.02;
requires 'JSON::Any' => 1.19;
+requires 'Test::Deep' => 0.104;
build_requires 'Test::More' => 0.7;
build_requires 'Catalyst::Model::DBIC::Schema' => 0.20;
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/Base.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/Base.pm 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/Base.pm 2009-05-16 11:51:55 UTC (rev 10173)
@@ -7,10 +7,17 @@
use DBIx::Class::ResultClass::HashRefInflator;
use JSON::Any;
+use Test::Deep::NoTest;
-__PACKAGE__->mk_accessors(qw(
- class create_requires update_requires update_allows $self->rs_stash_key create_allows list_count list_returns list_grouped_by list_search_exposes list_ordered_by rs_stash_key object_stash_key setup_list_method setup_dbic_args_method
- ));
+__PACKAGE__->mk_accessors(qw/
+ class create_requires
+ update_requires update_allows
+ create_allows
+ list_count list_returns list_prefetch list_prefetch_allows
+ list_grouped_by list_search_exposes list_ordered_by
+ rs_stash_key object_stash_key
+ setup_list_method setup_dbic_args_method
+/);
__PACKAGE__->config(
class => undef,
@@ -19,6 +26,8 @@
update_requires => [],
update_allows => [],
list_returns => [],
+ list_prefetch => undef,
+ list_prefetch_allows => [],
list_grouped_by => [],
list_search_exposes => [],
list_ordered_by => [],
@@ -27,16 +36,6 @@
rs_stash_key => 'class_rs'
);
-sub begin :Private {
- my ($self, $c) = @_;
-
- $c->forward('deserialize');
- if ($c->req->data) {
- $c->req->params($c->req->data);
- }
- $self->NEXT::begin($c);
-}
-
sub setup :Chained('specify.in.subclass.config') :CaptureArgs(0) :PathPart('specify.in.subclass.config') {
my ($self, $c) = @_;
@@ -57,7 +56,24 @@
sub generate_dbic_search_args :Private {
my ($self, $c) = @_;
-
+
+ my $args = {};
+ # do this before eventually calling expand_hash
+ my $prefetch = (exists $c->req->params->{list_prefetch} ? JSON::Any->from_json($c->req->params->{list_prefetch}) : undef) || ($self->list_prefetch ? $self->list_prefetch : undef);
+ if ($prefetch) {
+ # validate the prefetch param against list_prefetch_allows
+ foreach my $prefetch_allows (@{$self->list_prefetch_allows}) {
+ if (eq_deeply($prefetch, $prefetch_allows)) {
+ $args->{prefetch} = $prefetch;
+ # stop looking for a valid prefetch param
+ last;
+ }
+ }
+ unless (exists $args->{prefetch}) {
+ $self->push_error($c, { message => "prefetch validation failed" });
+ }
+ }
+
my $req_params = (grep { ref $_ } values %{$c->req->params}) ? $c->req->params : $self->expand_hash($c->req->params);
# if expand_hash didn't do anything, try json
unless (exists $req_params->{search} && ref $req_params->{search} eq 'HASH') {
@@ -70,7 +86,7 @@
return;
}
}
-
+
if ( my $a = $self->setup_list_method ) {
my $setup_action = $self->action_for($a);
if ( defined $setup_action ) {
@@ -82,7 +98,6 @@
my $source = $c->stash->{$self->rs_stash_key}->result_source;
my ($params, $join);
- my $args = {};
($params, $join) = $self->_format_search($c, { params => $req_params->{search}, source => $source }) if ($req_params->{search});
@@ -117,7 +132,7 @@
$c->log->error("setup_dbic_args_method was configured, but action $a not found");
}
}
-
+
return [$params, $args];
}
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/REST.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/REST.pm 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/REST.pm 2009-05-16 11:51:55 UTC (rev 10173)
@@ -74,6 +74,14 @@
=cut
+sub begin :Private {
+ my ($self, $c) = @_;
+
+ $c->forward('deserialize');
+ $c->req->params($c->req->data);
+ $self->NEXT::begin($c);
+}
+
# from Catalyst::Action::Serialize
sub deserialize :ActionClass('Deserialize') {
my ($self, $c) = @_;
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/RPC.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/RPC.pm 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API/RPC.pm 2009-05-16 11:51:55 UTC (rev 10173)
@@ -86,6 +86,14 @@
=cut
+sub begin :Private {
+ my ($self, $c) = @_;
+
+ $c->forward('deserialize');
+ $c->req->params($c->req->data);
+ $self->NEXT::begin($c);
+}
+
# from Catalyst::Action::Serialize
sub deserialize :ActionClass('Deserialize') {
my ($self, $c) = @_;
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API.pm 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/lib/Catalyst/Controller/DBIC/API.pm 2009-05-16 11:51:55 UTC (rev 10173)
@@ -5,11 +5,11 @@
=head1 VERSION
-Version 1.002000
+Version 1.003000
=cut
-our $VERSION = '1.002001';
+our $VERSION = '1.003000';
=head1 NAME
@@ -28,8 +28,15 @@
update_allows => ['name', 'age', 'nickname'], # columns that update allows
update_allows => ['name', 'age', 'nickname'], # columns that update allows
list_returns => [qw/name age/], # columns that list returns
+ list_prefetch => ['cds'], # relationships that are prefetched when no prefetch param is passed
+ list_prefetch_allows => [ # every possible prefetch param allowed
+ 'cds',
+ qw/ cds /,
+ { cds => 'tracks' },
+ { cds => [qw/ tracks /] }
+ ],
list_ordered_by => [qw/age/], # order of generated list
- list_search_exposes => [qw/age nickname/, { cd => [qw/title year/] }], # columns that can be searched on via list
+ list_search_exposes => [qw/age nickname/, { cds => [qw/title year/] }], # columns that can be searched on via list
);
# Provides the following functional endpoints:
@@ -93,6 +100,20 @@
Arguments to pass to L<DBIx::Class::ResultSet/select> when performing search for L</list>.
+=head2 list_prefetch
+
+Arguments to pass to L<DBIx::Class::ResultSet/prefetch> when performing search for L</list>.
+
+=head2 list_prefetch_allows
+
+Arrayref listing relationships that are allowed to be prefetched.
+This is necessary to avoid denial of service attacks in form of
+queries which would return a large number of data
+and unwanted disclosure of data.
+Every element of the arrayref is one allowed parameter to prefetch.
+So for three searches, all requiring different prefetch parameters,
+three elements have to be passed to list_prefetch_allows in the controller.
+
=head2 list_grouped_by
Arguments to pass to L<DBIx::Class::ResultSet/group_by> when performing search for L</list>.
@@ -313,7 +334,7 @@
Zbigniew Lukasiak <zzbbyy at gmail.com>
- Alexander Hartmaier <alex_hartmaier at hotmail.com>
+ Alexander Hartmaier <abraxxa at cpan.org>
=head1 SPECIAL THANKS
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm 2009-05-16 11:51:55 UTC (rev 10173)
@@ -10,7 +10,8 @@
class => 'RestTestDB::Artist',
create_requires => ['name'],
create_allows => ['name'],
- update_allows => ['name']
+ update_allows => ['name'],
+ list_prefetch_allows => [[qw/ cds /],{ 'cds' => 'tracks'}],
);
1;
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm 2009-05-16 11:51:55 UTC (rev 10173)
@@ -10,7 +10,8 @@
class => 'RestTestDB::Artist',
create_requires => ['name'],
create_allows => ['name'],
- update_allows => ['name']
+ update_allows => ['name'],
+ list_prefetch_allows => [[qw/ cds /],{ 'cds' => 'tracks'}],
);
1;
Modified: Catalyst-Controller-DBIC-API/1.003/trunk/t/rpc/list.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.003/trunk/t/rpc/list.t 2009-05-16 11:46:00 UTC (rev 10172)
+++ Catalyst-Controller-DBIC-API/1.003/trunk/t/rpc/list.t 2009-05-16 11:51:55 UTC (rev 10173)
@@ -60,6 +60,7 @@
is_deeply( { list => \@expected_response, success => 'true' }, $response, 'correct data returned for complex query' );
}
+exit;
{
my $uri = URI->new( $producer_list_url );
my $req = GET( $uri, 'Accept' => 'text/x-json' );
@@ -197,19 +198,6 @@
{
my $uri = URI->new( $cd_list_url );
- $uri->query_form({ 'search.artist.artistid' => 1 });
- my $req = GET( $uri, 'Accept' => 'text/x-json' );
- $mech->request($req);
- cmp_ok( $mech->status, '==', 200, 'search on rel column with same name fk request okay' );
-
- my @expected_response = map { { $_->get_columns } } $schema->resultset('CD')->search({'artist.artistid' => 1}, { join => 'artist' })->all;
- my $response = JSON::Syck::Load( $mech->content);
- #use Data::Dumper; warn Dumper($response, \@expected_response);
- is_deeply( { list => \@expected_response, success => 'true' }, $response, 'correct data returned for search on rel column with same name rel fk' );
-}
-
-{
- my $uri = URI->new( $cd_list_url );
$uri->query_form({ 'search.title' => 'Spoonful of bees', 'search.tracks.position' => 1 });
my $req = GET( $uri, 'Accept' => 'text/x-json' );
$mech->request($req);
More information about the Catalyst-commits
mailing list