moved prefetch_allows to StaticArguments to fix controller instantiation failures...
Alexander Hartmaier [Thu, 5 May 2011 14:12:09 +0000 (16:12 +0200)]
Changes
lib/Catalyst/Controller/DBIC/API.pm
lib/Catalyst/Controller/DBIC/API/Request.pm
lib/Catalyst/Controller/DBIC/API/RequestArguments.pm
lib/Catalyst/Controller/DBIC/API/StaticArguments.pm

diff --git a/Changes b/Changes
index 6b9e2a6..e1f5098 100644 (file)
--- a/Changes
+++ b/Changes
@@ -4,6 +4,7 @@ Revision history for Catalyst-Controller-DBIC-API: {{ $dist->version }}
 
 - Added has_errors method
 - Fixed tests to succeed with newer DBIx::Class versions
+- Fixed controller instantiation failures with Moose 2 in relation to prefetch
 
 2.003001  2011-02-16 17:52:37 Europe/Vienna
 
index b9a53d0..aa75619 100644 (file)
@@ -27,8 +27,9 @@ sub _build__json {
 }
 
 with 'Catalyst::Controller::DBIC::API::StoredResultSource',
-     'Catalyst::Controller::DBIC::API::StaticArguments',
-     'Catalyst::Controller::DBIC::API::RequestArguments' => { static => 1 };
+     'Catalyst::Controller::DBIC::API::StaticArguments';
+
+with 'Catalyst::Controller::DBIC::API::RequestArguments' => { static => 1 };
 
 __PACKAGE__->config();
 
index af7cff6..71aceb2 100644 (file)
@@ -34,12 +34,13 @@ has '_controller' =>
 
         $self->_set_class($new->class) if defined($new->class);
         $self->_set_application($new->_application);
-        $self->_set_prefetch_allows($new->prefetch_allows);
         $self->_set_search_exposes($new->search_exposes);
         $self->_set_select_exposes($new->select_exposes);
-    }
+    },
+    handles => ['prefetch_validator'],
 );
 
+
 with 'Catalyst::Controller::DBIC::API::StoredResultSource',
      'Catalyst::Controller::DBIC::API::RequestArguments',
      'Catalyst::Controller::DBIC::API::Request::Context';
index a6939f2..523c07f 100644 (file)
@@ -29,7 +29,7 @@ A Catalyst::Controller::DBIC::API::Validator instance used solely to validate pr
 
 =cut
 
-has [qw( search_validator select_validator prefetch_validator )] => (
+has [qw( search_validator select_validator )] => (
     is => 'ro',
     isa => 'Catalyst::Controller::DBIC::API::Validator',
     lazy => 1,
@@ -48,7 +48,7 @@ role {
 
     if($p->static)
     {
-        requires qw/check_has_relation check_column_relation/;
+        requires qw/check_has_relation check_column_relation prefetch_allows /;
     }
     else
     {
@@ -145,80 +145,20 @@ prefetch is passed to ->search to optimize the number of database fetches for jo
         trigger => sub
         {
             my ($self, $new) = @_;
-            if($self->has_prefetch_allows and @{$self->prefetch_allows})
-            {
-                foreach my $pf (@$new)
-                {
-                    if(HashRef->check($pf))
-                    {
-                        die qq|'${\Dumper($pf)}' is not an allowed prefetch in: ${\join("\n", @{$self->prefetch_validator->templates})}|
-                            unless $self->prefetch_validator->validate($pf)->[0];
-                    }
-                    else
-                    {
-                        die qq|'$pf' is not an allowed prefetch in: ${\join("\n", @{$self->prefetch_validator->templates})}|
-                            unless $self->prefetch_validator->validate({$pf => 1})->[0];
-                    }
-                }
-            }
-            else
-            {
-                return if not defined($new);
-                die 'Prefetching is not allowed' if @$new;
-            }
-        },
-    );
-
-=attribute_public prefetch_allows is: ro, isa: ArrayRef[ArrayRef|Str|HashRef]
-
-prefetch_allows limits what relations may be prefetched when executing searches with joins. 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.
 
-Like the synopsis in DBIC::API shows, you can declare a "template" of what is allowed (by using an '*'). Each element passed in, will be converted into a Data::DPath and added to the validator.
-
-    prefetch_allows => [ 'cds', { cds => tracks }, { cds => producers } ] # to be explicit
-    prefetch_allows => [ 'cds', { cds => '*' } ] # wildcard means the same thing
-
-=cut
-
-    has prefetch_allows =>
-    (
-        is => 'ro',
-        writer => '_set_prefetch_allows',
-        isa => ArrayRef[ArrayRef|Str|HashRef],
-        default => sub { [ ] },
-        predicate => 'has_prefetch_allows',
-        trigger => sub
-        {
-            my ($self, $new) = @_;
-
-            sub _check_rel {
-                my ($self, $rel, $static) = @_;
-                if(ArrayRef->check($rel))
-                {
-                    foreach my $rel_sub (@$rel)
-                    {
-                        $self->_check_rel($rel_sub, $static);
-                    }
-                }
-                elsif(HashRef->check($rel))
+            foreach my $pf (@$new)
+            {
+                if(HashRef->check($pf))
                 {
-                    while(my($k,$v) = each %$rel)
-                    {
-                        $self->check_has_relation($k, $v, undef, $static);
-                    }
-                    $self->prefetch_validator->load($rel);
+                    die qq|'${\Dumper($pf)}' is not an allowed prefetch in: ${\join("\n", @{$self->prefetch_validator->templates})}|
+                        unless $self->prefetch_validator->validate($pf)->[0];
                 }
                 else
                 {
-                    $self->check_has_relation($rel, undef, undef, $static);
-                    $self->prefetch_validator->load($rel);
+                    die qq|'$pf' is not an allowed prefetch in: ${\join("\n", @{$self->prefetch_validator->templates})}|
+                        unless $self->prefetch_validator->validate({$pf => 1})->[0];
                 }
             }
-
-            foreach my $rel (@$new)
-            {
-                $self->_check_rel($rel, $p->static);
-            }
         },
     );
 
index e2c2c90..ae53e09 100644 (file)
@@ -50,6 +50,72 @@ foreach my $var (qw/create_requires create_allows update_requires update_allows/
     before "insert_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) }; #"
 }
 
+=attribute_public prefetch_allows is: ro, isa: ArrayRef[ArrayRef|Str|HashRef]
+
+prefetch_allows limits what relations may be prefetched when executing searches with joins. 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.
+
+Like the synopsis in DBIC::API shows, you can declare a "template" of what is allowed (by using an '*'). Each element passed in, will be converted into a Data::DPath and added to the validator.
+
+    prefetch_allows => [ 'cds', { cds => tracks }, { cds => producers } ] # to be explicit
+    prefetch_allows => [ 'cds', { cds => '*' } ] # wildcard means the same thing
+
+=cut
+
+has 'prefetch_allows' => (
+    is => 'ro',
+    writer => '_set_prefetch_allows',
+    isa => ArrayRef[ArrayRef|Str|HashRef],
+    default => sub { [ ] },
+    predicate => 'has_prefetch_allows',
+    traits => ['Array'],
+    handles =>
+    {
+        all_prefetch_allows => 'elements',
+    },
+);
+
+has 'prefetch_validator' => (
+    is => 'ro',
+    isa => 'Catalyst::Controller::DBIC::API::Validator',
+    lazy_build => 1,
+);
+
+sub _build_prefetch_validator {
+    my $self = shift;
+
+    sub _check_rel {
+        my ($self, $rel, $static, $validator) = @_;
+        if(ArrayRef->check($rel))
+        {
+            foreach my $rel_sub (@$rel)
+            {
+                _check_rel($self, $rel_sub, $static, $validator);
+            }
+        }
+        elsif(HashRef->check($rel))
+        {
+            while(my($k,$v) = each %$rel)
+            {
+                $self->check_has_relation($k, $v, undef, $static);
+            }
+            $validator->load($rel);
+        }
+        else
+        {
+            $self->check_has_relation($rel, undef, undef, $static);
+            $validator->load($rel);
+        }
+    }
+
+    my $validator = Catalyst::Controller::DBIC::API::Validator->new;
+
+    foreach my $rel ($self->all_prefetch_allows) {
+        _check_rel($self, $rel, 1, $validator);
+    }
+
+    return $validator;
+}
+
 =attribute_public count_arg is: ro, isa: Str, default: 'list_count'
 
 count_arg controls how to reference 'count' in the the request_data