use Test::Deep::NoTest('eq_deeply');
use MooseX::Types::Moose(':all');
use Moose::Util;
-use Scalar::Util('blessed', 'reftype');
+use Scalar::Util( 'blessed', 'reftype' );
use Try::Tiny;
use Catalyst::Controller::DBIC::API::Request;
use namespace::autoclean;
has '_json' => (
- is => 'ro',
- isa => 'JSON',
+ is => 'ro',
+ isa => 'JSON',
lazy_build => 1,
);
sub _build__json {
+
# no ->utf8 here because the request params get decoded by Catalyst
return JSON->new;
}
with 'Catalyst::Controller::DBIC::API::StoredResultSource',
- 'Catalyst::Controller::DBIC::API::StaticArguments';
+ 'Catalyst::Controller::DBIC::API::StaticArguments';
with 'Catalyst::Controller::DBIC::API::RequestArguments' => { static => 1 };
BEGIN { extends 'Catalyst::Controller::DBIC::API::RPC' }
__PACKAGE__->config
- ( action => { setup => { PathPart => 'artist', Chained => '/api/rpc/rpc_base' } }, # define parent chain action and partpath
+ ( # define parent chain action and PathPart
+ action => {
+ setup => {
+ Chained => '/api/rpc/rpc_base',
+ PathPart => 'artist',
+ }
+ },
class => 'MyAppDB::Artist',
resultset_class => 'MyAppDB::ResultSet::Artist',
create_requires => ['name', 'age'],
create_allows => ['nickname'],
update_allows => ['name', 'age', 'nickname'],
update_allows => ['name', 'age', 'nickname'],
- select => [qw/name age/],
+ select => ['name', 'age'],
prefetch => ['cds'],
prefetch_allows => [
'cds',
- qw/ cds /,
{ cds => 'tracks' },
- { cds => [qw/ tracks /] },
+ { cds => ['tracks'] },
],
- ordered_by => [qw/age/],
- search_exposes => [qw/age nickname/, { cds => [qw/title year/] }],
+ ordered_by => ['age'],
+ search_exposes => ['age', 'nickname', { cds => ['title', 'year'] }],
data_root => 'data',
use_json_boolean => 1,
return_object => 1,
=cut
-sub begin :Private
-{
- my ($self, $c) = @_;
+sub begin : Private {
+ my ( $self, $c ) = @_;
- Moose::Util::ensure_all_roles($c->req, 'Catalyst::Controller::DBIC::API::Request');
+ Moose::Util::ensure_all_roles( $c->req,
+ 'Catalyst::Controller::DBIC::API::Request' );
}
=method_protected setup
:Chained('specify.in.subclass.config') :CaptureArgs(0) :PathPart('specify.in.subclass.config')
-This action is the chain root of the controller. It must either be overridden or configured to provide a base pathpart to the action and also a parent action. For example, for class MyAppDB::Track you might have
+This action is the chain root of the controller. It must either be overridden or
+configured to provide a base PathPart to the action and also a parent action.
+For example, for class MyAppDB::Track you might have
package MyApp::Controller::API::RPC::Track;
use Moose;
=cut
-sub setup :Chained('specify.in.subclass.config') :CaptureArgs(0) :PathPart('specify.in.subclass.config') {}
+sub setup : Chained('specify.in.subclass.config') : CaptureArgs(0) :
+ PathPart('specify.in.subclass.config') { }
=method_protected deserialize
=cut
-sub deserialize :Chained('setup') :CaptureArgs(0) :PathPart('') :ActionClass('Deserialize')
-{
- my ($self, $c) = @_;
+sub deserialize : Chained('setup') : CaptureArgs(0) : PathPart('') :
+ ActionClass('Deserialize') {
+ my ( $self, $c ) = @_;
my $req_params;
- if ($c->req->data && scalar(keys %{$c->req->data}))
- {
+ if ( $c->req->data && scalar( keys %{ $c->req->data } ) ) {
$req_params = $c->req->data;
}
- else
- {
- $req_params = CGI::Expand->expand_hash($c->req->params);
-
- foreach my $param (@{[$self->search_arg, $self->count_arg, $self->page_arg, $self->offset_arg, $self->ordered_by_arg, $self->grouped_by_arg, $self->prefetch_arg]})
+ else {
+ $req_params = CGI::Expand->expand_hash( $c->req->params );
+
+ foreach my $param (
+ @{ [ $self->search_arg, $self->count_arg,
+ $self->page_arg, $self->offset_arg,
+ $self->ordered_by_arg, $self->grouped_by_arg,
+ $self->prefetch_arg
+ ]
+ }
+ )
{
# these params can also be composed of JSON
# but skip if the parameter is not provided
next if not exists $req_params->{$param};
+
# find out if CGI::Expand was involved
- if (ref $req_params->{$param} eq 'HASH')
- {
- for my $key ( keys %{$req_params->{$param}} )
- {
+ if ( ref $req_params->{$param} eq 'HASH' ) {
+ for my $key ( keys %{ $req_params->{$param} } ) {
+
# copy the value because JSON::XS will alter it
# even if decoding failed
my $value = $req_params->{$param}->{$key};
- try
- {
+ try {
my $deserialized = $self->_json->decode($value);
$req_params->{$param}->{$key} = $deserialized;
}
- catch
- {
- $c->log->debug("Param '$param.$key' did not deserialize appropriately: $_")
- if $c->debug;
+ catch {
+ $c->log->debug(
+ "Param '$param.$key' did not deserialize appropriately: $_"
+ ) if $c->debug;
}
}
}
- else
- {
- try
- {
- my $value = $req_params->{$param};
+ else {
+ try {
+ my $value = $req_params->{$param};
my $deserialized = $self->_json->decode($value);
$req_params->{$param} = $deserialized;
}
- catch
- {
- $c->log->debug("Param '$param' did not deserialize appropriately: $_")
- if $c->debug;
+ catch {
+ $c->log->debug(
+ "Param '$param' did not deserialize appropriately: $_"
+ ) if $c->debug;
}
}
}
}
- $self->inflate_request($c, $req_params);
+ $self->inflate_request( $c, $req_params );
}
=method_protected generate_rs
=cut
-sub generate_rs
-{
- my ($self, $c) = @_;
+sub generate_rs {
+ my ( $self, $c ) = @_;
- return $c->model($c->stash->{class} || $self->class);
+ return $c->model( $c->stash->{class} || $self->class );
}
=method_protected inflate_request
=cut
-sub inflate_request
-{
- my ($self, $c, $params) = @_;
+sub inflate_request {
+ my ( $self, $c, $params ) = @_;
- try
- {
+ try {
# set static arguments
$c->req->_set_controller($self);
$c->req->_set_request_data($params);
# set the current resultset
- $c->req->_set_current_result_set($self->generate_rs($c));
+ $c->req->_set_current_result_set( $self->generate_rs($c) );
}
- catch
- {
+ catch {
$c->log->error($_);
- $self->push_error($c, { message => $_ });
+ $self->push_error( $c, { message => $_ } );
$c->detach();
}
}
=cut
-sub object_with_id :Chained('deserialize') :CaptureArgs(1) :PathPart('')
-{
- my ($self, $c, $id) = @_;
+sub object_with_id : Chained('deserialize') : CaptureArgs(1) : PathPart('') {
+ my ( $self, $c, $id ) = @_;
+
+ my $vals = $c->req->request_data->{ $self->data_root };
+ unless ( defined($vals) ) {
- my $vals = $c->req->request_data->{$self->data_root};
- unless(defined($vals))
- {
# no data root, assume the request_data itself is the payload
$vals = $c->req->request_data;
}
- try
- {
+ try {
# there can be only one set of data
- $c->req->add_object([$self->object_lookup($c, $id), $vals]);
+ $c->req->add_object( [ $self->object_lookup( $c, $id ), $vals ] );
}
- catch
- {
+ catch {
$c->log->error($_);
- $self->push_error($c, { message => $_ });
+ $self->push_error( $c, { message => $_ } );
$c->detach();
}
}
=cut
-sub objects_no_id :Chained('deserialize') :CaptureArgs(0) :PathPart('')
-{
- my ($self, $c) = @_;
+sub objects_no_id : Chained('deserialize') : CaptureArgs(0) : PathPart('') {
+ my ( $self, $c ) = @_;
- if($c->req->has_request_data)
- {
+ if ( $c->req->has_request_data ) {
my $data = $c->req->request_data;
my $vals;
- if(exists($data->{$self->data_root}) && defined($data->{$self->data_root}))
+ if ( exists( $data->{ $self->data_root } )
+ && defined( $data->{ $self->data_root } ) )
{
- my $root = $data->{$self->data_root};
- if(reftype($root) eq 'ARRAY')
- {
+ my $root = $data->{ $self->data_root };
+ if ( reftype($root) eq 'ARRAY' ) {
$vals = $root;
}
- elsif(reftype($root) eq 'HASH')
- {
+ elsif ( reftype($root) eq 'HASH' ) {
$vals = [$root];
}
- else
- {
+ else {
$c->log->error('Invalid request data');
- $self->push_error($c, { message => 'Invalid request data' });
+ $self->push_error( $c,
+ { message => 'Invalid request data' } );
$c->detach();
}
}
- else
- {
+ else {
# no data root, assume the request_data itself is the payload
- $vals = [$c->req->request_data];
+ $vals = [ $c->req->request_data ];
}
- foreach my $val (@$vals)
- {
- unless(exists($val->{id}))
- {
- $c->req->add_object([$c->req->current_result_set->new_result({}), $val]);
+ foreach my $val (@$vals) {
+ unless ( exists( $val->{id} ) ) {
+ $c->req->add_object(
+ [ $c->req->current_result_set->new_result( {} ), $val ] );
next;
}
- try
- {
- $c->req->add_object([$self->object_lookup($c, $val->{id}), $val]);
+ try {
+ $c->req->add_object(
+ [ $self->object_lookup( $c, $val->{id} ), $val ] );
}
- catch
- {
+ catch {
$c->log->error($_);
- $self->push_error($c, { message => $_ });
+ $self->push_error( $c, { message => $_ } );
$c->detach();
}
}
=cut
-sub object_lookup
-{
- my ($self, $c, $id) = @_;
+sub object_lookup {
+ my ( $self, $c, $id ) = @_;
die 'No valid ID provided for look up' unless defined $id and length $id;
my $object = $c->req->current_result_set->find($id);
=cut
-sub list
-{
- my ($self, $c) = @_;
+sub list {
+ my ( $self, $c ) = @_;
$self->list_munge_parameters($c);
$self->list_perform_search($c);
=cut
-sub list_munge_parameters { } # noop by default
+sub list_munge_parameters { } # noop by default
=method_protected list_perform_search
=cut
-sub list_perform_search
-{
- my ($self, $c) = @_;
+sub list_perform_search {
+ my ( $self, $c ) = @_;
- try
- {
+ try {
my $req = $c->req;
- my $rs = $req->current_result_set->search
- (
- $req->search_parameters,
- $req->search_attributes
- );
+ my $rs =
+ $req->current_result_set->search( $req->search_parameters,
+ $req->search_attributes );
$req->_set_current_result_set($rs);
- $req->_set_search_total_entries($req->current_result_set->pager->total_entries)
- if $req->has_search_attributes && (exists($req->search_attributes->{page}) && defined($req->search_attributes->{page}) && length($req->search_attributes->{page}));
+ $req->_set_search_total_entries(
+ $req->current_result_set->pager->total_entries )
+ if $req->has_search_attributes
+ && ( exists( $req->search_attributes->{page} )
+ && defined( $req->search_attributes->{page} )
+ && length( $req->search_attributes->{page} ) );
}
- catch
- {
+ catch {
$c->log->error($_);
- $self->push_error($c, { message => 'a database error has occured.' });
+ $self->push_error( $c,
+ { message => 'a database error has occured.' } );
$c->detach();
}
}
=cut
-sub list_format_output
-{
- my ($self, $c) = @_;
+sub list_format_output {
+ my ( $self, $c ) = @_;
my $rs = $c->req->current_result_set->search;
- $rs->result_class($self->result_class) if $self->result_class;
+ $rs->result_class( $self->result_class ) if $self->result_class;
- try
- {
- my $output = {};
+ try {
+ my $output = {};
my $formatted = [];
- foreach my $row ($rs->all)
- {
- push(@$formatted, $self->row_format_output($c, $row));
+ foreach my $row ( $rs->all ) {
+ push( @$formatted, $self->row_format_output( $c, $row ) );
}
- $output->{$self->data_root} = $formatted;
+ $output->{ $self->data_root } = $formatted;
- if ($c->req->has_search_total_entries)
- {
- $output->{$self->total_entries_arg} = $c->req->search_total_entries + 0;
+ if ( $c->req->has_search_total_entries ) {
+ $output->{ $self->total_entries_arg } =
+ $c->req->search_total_entries + 0;
}
- $c->stash->{$self->stash_key} = $output;
+ $c->stash->{ $self->stash_key } = $output;
}
- catch
- {
+ catch {
$c->log->error($_);
- $self->push_error($c, { message => 'a database error has occured.' });
+ $self->push_error( $c,
+ { message => 'a database error has occured.' } );
$c->detach();
}
}
=cut
-sub row_format_output
-{
+sub row_format_output {
+
#my ($self, $c, $row) = @_;
- my ($self, undef, $row) = @_;
- return $row; # passthrough by default
+ my ( $self, undef, $row ) = @_;
+ return $row; # passthrough by default
}
=method_protected item
=cut
-sub item
-{
- my ($self, $c) = @_;
+sub item {
+ my ( $self, $c ) = @_;
- if($c->req->count_objects != 1)
- {
+ if ( $c->req->count_objects != 1 ) {
$c->log->error($_);
- $self->push_error($c, { message => 'No objects on which to operate' });
+ $self->push_error( $c,
+ { message => 'No objects on which to operate' } );
$c->detach();
}
- else
- {
- $c->stash->{$self->stash_key}->{$self->item_root} = $self->each_object_inflate($c, $c->req->get_object(0)->[0]);
+ else {
+ $c->stash->{ $self->stash_key }->{ $self->item_root } =
+ $self->each_object_inflate( $c, $c->req->get_object(0)->[0] );
}
}
=cut
-sub update_or_create
-{
- my ($self, $c) = @_;
+sub update_or_create {
+ my ( $self, $c ) = @_;
- if($c->req->has_objects)
- {
+ if ( $c->req->has_objects ) {
$self->validate_objects($c);
- $self->transact_objects($c, sub { $self->save_objects($c, @_) } );
+ $self->transact_objects( $c, sub { $self->save_objects( $c, @_ ) } );
}
- else
- {
+ else {
$c->log->error($_);
- $self->push_error($c, { message => 'No objects on which to operate' });
+ $self->push_error( $c,
+ { message => 'No objects on which to operate' } );
$c->detach();
}
}
=cut
-sub transact_objects
-{
- my ($self, $c, $coderef) = @_;
-
- try
- {
- $self->stored_result_source->schema->txn_do
- (
- $coderef,
- $c->req->objects
- );
+sub transact_objects {
+ my ( $self, $c, $coderef ) = @_;
+
+ try {
+ $self->stored_result_source->schema->txn_do( $coderef,
+ $c->req->objects );
}
- catch
- {
+ catch {
$c->log->error($_);
- $self->push_error($c, { message => 'a database error has occured.' });
+ $self->push_error( $c,
+ { message => 'a database error has occured.' } );
$c->detach();
}
}
=cut
-sub validate_objects
-{
- my ($self, $c) = @_;
+sub validate_objects {
+ my ( $self, $c ) = @_;
- try
- {
- foreach my $obj ($c->req->all_objects)
- {
- $obj->[1] = $self->validate_object($c, $obj);
+ try {
+ foreach my $obj ( $c->req->all_objects ) {
+ $obj->[1] = $self->validate_object( $c, $obj );
}
}
- catch
- {
+ catch {
my $err = $_;
$c->log->error($err);
$err =~ s/\s+at\s+.+\n$//g;
- $self->push_error($c, { message => $err });
+ $self->push_error( $c, { message => $err } );
$c->detach();
}
}
=cut
-sub validate_object
-{
- my ($self, $c, $obj) = @_;
- my ($object, $params) = @$obj;
+sub validate_object {
+ my ( $self, $c, $obj ) = @_;
+ my ( $object, $params ) = @$obj;
my %values;
- my %requires_map = map
- {
- $_ => 1
- }
- @{
- ($object->in_storage)
+ my %requires_map = map { $_ => 1 } @{
+ ( $object->in_storage )
? []
: $c->stash->{create_requires} || $self->create_requires
};
- my %allows_map = map
- {
- (ref $_) ? %{$_} : ($_ => 1)
- }
- (
+ my %allows_map = map { ( ref $_ ) ? %{$_} : ( $_ => 1 ) } (
keys %requires_map,
- @{
- ($object->in_storage)
- ? ($c->stash->{update_allows} || $self->update_allows)
- : ($c->stash->{create_allows} || $self->create_allows)
+ @{ ( $object->in_storage )
+ ? ( $c->stash->{update_allows} || $self->update_allows )
+ : ( $c->stash->{create_allows} || $self->create_allows )
}
);
- foreach my $key (keys %allows_map)
- {
+ foreach my $key ( keys %allows_map ) {
+
# check value defined if key required
my $allowed_fields = $allows_map{$key};
- if (ref $allowed_fields)
- {
+ if ( ref $allowed_fields ) {
my $related_source = $object->result_source->related_source($key);
my $related_params = $params->{$key};
my %allowed_related_map = map { $_ => 1 } @$allowed_fields;
- my $allowed_related_cols = ($allowed_related_map{'*'}) ? [$related_source->columns] : $allowed_fields;
-
- foreach my $related_col (@{$allowed_related_cols})
- {
- if (defined(my $related_col_value = $related_params->{$related_col})) {
+ my $allowed_related_cols =
+ ( $allowed_related_map{'*'} )
+ ? [ $related_source->columns ]
+ : $allowed_fields;
+
+ foreach my $related_col ( @{$allowed_related_cols} ) {
+ if (defined(
+ my $related_col_value =
+ $related_params->{$related_col}
+ )
+ )
+ {
$values{$key}{$related_col} = $related_col_value;
}
}
}
- else
- {
+ else {
my $value = $params->{$key};
- if ($requires_map{$key})
- {
- unless (defined($value))
- {
+ if ( $requires_map{$key} ) {
+ unless ( defined($value) ) {
+
# if not defined look for default
- $value = $object->result_source->column_info($key)->{default_value};
- unless (defined $value)
- {
+ $value = $object->result_source->column_info($key)
+ ->{default_value};
+ unless ( defined $value ) {
die "No value supplied for ${key} and no default";
}
}
}
# check for multiple values
- if (ref($value) && !(reftype($value) eq reftype(JSON::true)))
+ if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) )
{
require Data::Dumper;
- die "Multiple values for '${key}': ${\Data::Dumper::Dumper($value)}";
+ die
+ "Multiple values for '${key}': ${\Data::Dumper::Dumper($value)}";
}
# check exists so we don't just end up with hash of undefs
# check defined to account for default values being used
- $values{$key} = $value if exists $params->{$key} || defined $value;
+ $values{$key} = $value
+ if exists $params->{$key} || defined $value;
}
}
- unless (keys %values || !$object->in_storage)
- {
+ unless ( keys %values || !$object->in_storage ) {
die 'No valid keys passed';
}
=cut
-sub delete
-{
- my ($self, $c) = @_;
+sub delete {
+ my ( $self, $c ) = @_;
- if($c->req->has_objects)
- {
- $self->transact_objects($c, sub { $self->delete_objects($c, @_) });
+ if ( $c->req->has_objects ) {
+ $self->transact_objects( $c,
+ sub { $self->delete_objects( $c, @_ ) } );
$c->req->clear_objects;
}
- else
- {
+ else {
$c->log->error($_);
- $self->push_error($c, { message => 'No objects on which to operate' });
+ $self->push_error( $c,
+ { message => 'No objects on which to operate' } );
$c->detach();
}
}
=cut
-sub save_objects
-{
- my ($self, $c, $objects) = @_;
+sub save_objects {
+ my ( $self, $c, $objects ) = @_;
- foreach my $obj (@$objects)
- {
- $self->save_object($c, $obj);
+ foreach my $obj (@$objects) {
+ $self->save_object( $c, $obj );
}
}
=cut
-sub save_object
-{
- my ($self, $c, $obj) = @_;
+sub save_object {
+ my ( $self, $c, $obj ) = @_;
- my ($object, $params) = @$obj;
+ my ( $object, $params ) = @$obj;
- if ($object->in_storage)
- {
- $self->update_object_from_params($c, $object, $params);
+ if ( $object->in_storage ) {
+ $self->update_object_from_params( $c, $object, $params );
}
- else
- {
- $self->insert_object_from_params($c, $object, $params);
+ else {
+ $self->insert_object_from_params( $c, $object, $params );
}
}
=cut
-sub update_object_from_params
-{
- my ($self, $c, $object, $params) = @_;
+sub update_object_from_params {
+ my ( $self, $c, $object, $params ) = @_;
- foreach my $key (keys %$params)
- {
+ foreach my $key ( keys %$params ) {
my $value = $params->{$key};
- if (ref($value) && !(reftype($value) eq reftype(JSON::true)))
- {
- $self->update_object_relation($c, $object, delete $params->{$key}, $key);
+ if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) ) {
+ $self->update_object_relation( $c, $object,
+ delete $params->{$key}, $key );
}
+
# accessor = colname
- elsif ($object->can($key)) {
+ elsif ( $object->can($key) ) {
$object->$key($value);
}
+
# accessor != colname
else {
- my $accessor = $object->result_source->column_info($key)->{accessor};
+ my $accessor =
+ $object->result_source->column_info($key)->{accessor};
$object->$accessor($value);
}
}
=cut
-sub update_object_relation
-{
- my ($self, $c, $object, $related_params, $relation) = @_;
- my $row = $object->find_related($relation, {} , {});
+sub update_object_relation {
+ my ( $self, $c, $object, $related_params, $relation ) = @_;
+ my $row = $object->find_related( $relation, {}, {} );
if ($row) {
- foreach my $key (keys %$related_params) {
+ foreach my $key ( keys %$related_params ) {
my $value = $related_params->{$key};
- if (ref($value) && !(reftype($value) eq reftype(JSON::true)))
+ if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) )
{
- $self->update_object_relation($c, $row, delete $related_params->{$key}, $key);
+ $self->update_object_relation( $c, $row,
+ delete $related_params->{$key}, $key );
}
+
# accessor = colname
- elsif ($row->can($key)) {
+ elsif ( $row->can($key) ) {
$row->$key($value);
}
+
# accessor != colname
else {
- my $accessor = $row->result_source->column_info($key)->{accessor};
+ my $accessor =
+ $row->result_source->column_info($key)->{accessor};
$row->$accessor($value);
}
}
$row->update();
}
else {
- $object->create_related($relation, $related_params);
+ $object->create_related( $relation, $related_params );
}
}
=cut
-sub insert_object_from_params
-{
+sub insert_object_from_params {
+
#my ($self, $c, $object, $params) = @_;
- my ($self, undef, $object, $params) = @_;
+ my ( $self, undef, $object, $params ) = @_;
my %rels;
- while (my ($key, $value) = each %{ $params }) {
- if (ref($value) && !(reftype($value) eq reftype(JSON::true))) {
+ while ( my ( $key, $value ) = each %{$params} ) {
+ if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) ) {
$rels{$key} = $value;
}
+
# accessor = colname
- elsif ($object->can($key)) {
+ elsif ( $object->can($key) ) {
$object->$key($value);
}
+
# accessor != colname
else {
- my $accessor = $object->result_source->column_info($key)->{accessor};
+ my $accessor =
+ $object->result_source->column_info($key)->{accessor};
$object->$accessor($value);
}
}
$object->insert;
- while (my ($k, $v) = each %rels) {
- $object->create_related($k, $v);
+ while ( my ( $k, $v ) = each %rels ) {
+ $object->create_related( $k, $v );
}
}
=cut
-sub delete_objects
-{
- my ($self, $c, $objects) = @_;
+sub delete_objects {
+ my ( $self, $c, $objects ) = @_;
- map { $self->delete_object($c, $_->[0]) } @$objects;
+ map { $self->delete_object( $c, $_->[0] ) } @$objects;
}
=method_protected delete_object
=cut
-sub delete_object
-{
+sub delete_object {
+
#my ($self, $c, $object) = @_;
- my ($self, undef, $object) = @_;
+ my ( $self, undef, $object ) = @_;
$object->delete;
}
=cut
-sub end :Private
-{
- my ($self, $c) = @_;
+sub end : Private {
+ my ( $self, $c ) = @_;
# don't change the http status code if already set elsewhere
- unless ($c->res->status && $c->res->status != 200) {
- if ($self->has_errors($c)) {
+ unless ( $c->res->status && $c->res->status != 200 ) {
+ if ( $self->has_errors($c) ) {
$c->res->status(400);
}
else {
}
}
- if ($c->res->status == 200) {
- $c->stash->{$self->stash_key}->{success} = $self->use_json_boolean ? JSON::true : 'true';
- if($self->return_object && $c->req->has_objects) {
+ if ( $c->res->status == 200 ) {
+ $c->stash->{ $self->stash_key }->{success} =
+ $self->use_json_boolean ? JSON::true : 'true';
+ if ( $self->return_object && $c->req->has_objects ) {
my $returned_objects = [];
- push(@$returned_objects, $self->each_object_inflate($c, $_)) for map { $_->[0] } $c->req->all_objects;
- $c->stash->{$self->stash_key}->{$self->data_root} = scalar(@$returned_objects) > 1 ? $returned_objects : $returned_objects->[0];
+ push( @$returned_objects, $self->each_object_inflate( $c, $_ ) )
+ for map { $_->[0] } $c->req->all_objects;
+ $c->stash->{ $self->stash_key }->{ $self->data_root } =
+ scalar(@$returned_objects) > 1
+ ? $returned_objects
+ : $returned_objects->[0];
}
}
else {
- $c->stash->{$self->stash_key}->{success} = $self->use_json_boolean ? JSON::false : 'false';
- $c->stash->{$self->stash_key}->{messages} = $self->get_errors($c)
+ $c->stash->{ $self->stash_key }->{success} =
+ $self->use_json_boolean ? JSON::false : 'false';
+ $c->stash->{ $self->stash_key }->{messages} = $self->get_errors($c)
if $self->has_errors($c);
+
# don't return data for error responses
- delete $c->stash->{$self->stash_key}->{$self->data_root};
+ delete $c->stash->{ $self->stash_key }->{ $self->data_root };
}
$c->forward('serialize');
=cut
-sub each_object_inflate
-{
+sub each_object_inflate {
+
#my ($self, $c, $object) = @_;
- my ($self, undef, $object) = @_;
+ my ( $self, undef, $object ) = @_;
return { $object->get_columns };
}
=cut
# from Catalyst::Action::Serialize
-sub serialize :ActionClass('Serialize') { }
+sub serialize : ActionClass('Serialize') { }
=method_protected push_error
=cut
-sub push_error
-{
+sub push_error {
my ( $self, $c, $params ) = @_;
die 'Catalyst app object missing'
unless defined $c;
my $error = 'unknown error';
- if (exists $params->{message}) {
+ if ( exists $params->{message} ) {
$error = $params->{message};
+
# remove newline from die "error message\n" which is required to not
# have the filename and line number in the error text
$error =~ s/\n$//;
}
- push( @{$c->stash->{_dbic_crud_errors}}, $error);
+ push( @{ $c->stash->{_dbic_crud_errors} }, $error );
}
=method_protected get_errors
=cut
-sub get_errors
-{
+sub get_errors {
my ( $self, $c ) = @_;
die 'Catalyst app object missing'
unless defined $c;
=cut
-has parent =>
-(
- is => 'ro',
- isa => JoinBuilder,
+has parent => (
+ is => 'ro',
+ isa => JoinBuilder,
predicate => 'has_parent',
- weak_ref => 1,
- trigger => sub { my ($self, $new) = @_; $new->add_child($self); },
+ weak_ref => 1,
+ trigger => sub { my ( $self, $new ) = @_; $new->add_child($self); },
);
=attribute_public children is: ro, isa: ArrayRef['Catalyst::Controller::DBIC::API::JoinBuilder'], traits => ['Array']
all_children => 'elements'
has_children => 'count'
- add_child => 'push'
+ add_child => 'push'
=cut
-has children =>
-(
- is => 'ro',
- isa => ArrayRef[JoinBuilder],
- traits => ['Array'],
+has children => (
+ is => 'ro',
+ isa => ArrayRef [JoinBuilder],
+ traits => ['Array'],
default => sub { [] },
- handles =>
- {
+ handles => {
all_children => 'elements',
has_children => 'count',
- add_child => 'push',
+ add_child => 'push',
}
);
=cut
-has joins =>
-(
- is => 'ro',
- isa => HashRef,
+has joins => (
+ is => 'ro',
+ isa => HashRef,
lazy_build => 1,
);
=cut
-has name =>
-(
- is => 'ro',
- isa => Str,
+has name => (
+ is => 'ro',
+ isa => Str,
required => 1,
);
=cut
-sub _build_joins
-{
+sub _build_joins {
my ($self) = @_;
my $parent;
- while(my $found = $self->parent)
- {
- if($found->has_parent)
- {
+ while ( my $found = $self->parent ) {
+ if ( $found->has_parent ) {
$self = $found;
next;
}
}
my $builder;
- $builder = sub
- {
+ $builder = sub {
my ($node) = @_;
my $foo = {};
- map { $foo->{$_->name} = $builder->($_) } $node->all_children;
+ map { $foo->{ $_->name } = $builder->($_) } $node->all_children;
return $foo;
};
- return $builder->($parent || $self);
+ return $builder->( $parent || $self );
}
=head1 DESCRIPTION
'map' => {
'application/x-www-form-urlencoded' => 'JSON',
'application/json' => 'JSON',
- });
+ }
+);
=head1 DESCRIPTION
=cut
-sub update_or_create_objects : POST PUT Chained('objects_no_id') PathPart('') Args(0)
-{
- my ( $self, $c ) = @_;
+sub update_or_create_objects : POST PUT Chained('objects_no_id') PathPart('')
+ Args(0) {
+ my ( $self, $c ) = @_;
$self->update_or_create($c);
}
=cut
-sub delete_many_objects : DELETE Chained('objects_no_id') PathPart('') Args(0)
-{
- my ( $self, $c ) = @_;
+sub delete_many_objects : DELETE Chained('objects_no_id') PathPart('')
+ Args(0) {
+ my ( $self, $c ) = @_;
$self->delete($c);
}
=cut
-sub list_objects : GET Chained('objects_no_id') PathPart('') Args(0)
-{
- my ( $self, $c ) = @_;
+sub list_objects : GET Chained('objects_no_id') PathPart('') Args(0) {
+ my ( $self, $c ) = @_;
$self->list($c);
}
=cut
-sub update_or_create_one_object : POST PUT Chained('object_with_id') PathPart('') Args(0)
-{
- my ( $self, $c ) = @_;
+sub update_or_create_one_object : POST PUT Chained('object_with_id')
+ PathPart('') Args(0) {
+ my ( $self, $c ) = @_;
$self->update_or_create($c);
}
sub delete_one_object : DELETE Chained('object_with_id') PathPart('') Args(0)
{
- my ( $self, $c ) = @_;
+ my ( $self, $c ) = @_;
$self->delete($c);
}
=cut
-sub list_one_object : GET Chained('object_with_id') PathPart('') Args(0)
-{
- my ( $self, $c ) = @_;
+sub list_one_object : GET Chained('object_with_id') PathPart('') Args(0) {
+ my ( $self, $c ) = @_;
$self->item($c);
}
package Catalyst::Controller::DBIC::API::RPC;
+
#ABSTRACT: Provides an RPC interface to DBIx::Class
use Moose;
=cut
-sub create :Chained('objects_no_id') :PathPart('create') :Args(0)
-{
- my ($self, $c) = @_;
+sub create : Chained('objects_no_id') : PathPart('create') : Args(0) {
+ my ( $self, $c ) = @_;
$self->update_or_create($c);
}
=cut
-sub list :Chained('deserialize') :PathPart('list') :Args(0)
-{
- my ($self, $c) = @_;
+sub list : Chained('deserialize') : PathPart('list') : Args(0) {
+ my ( $self, $c ) = @_;
$self->next::method($c);
}
=cut
-sub item :Chained('object_with_id') :PathPart('') :Args(0)
-{
- my ($self, $c) = @_;
+sub item : Chained('object_with_id') : PathPart('') : Args(0) {
+ my ( $self, $c ) = @_;
$self->next::method($c);
}
=cut
-sub update :Chained('object_with_id') :PathPart('update') :Args(0)
-{
- my ($self, $c) = @_;
+sub update : Chained('object_with_id') : PathPart('update') : Args(0) {
+ my ( $self, $c ) = @_;
$self->update_or_create($c);
}
=cut
-sub delete :Chained('object_with_id') :PathPart('delete') :Args(0)
-{
- my ($self, $c) = @_;
+sub delete : Chained('object_with_id') : PathPart('delete') : Args(0) {
+ my ( $self, $c ) = @_;
$self->next::method($c);
}
=cut
-sub update_bulk :Chained('objects_no_id') :PathPart('update') :Args(0)
-{
- my ($self, $c) = @_;
+sub update_bulk : Chained('objects_no_id') : PathPart('update') : Args(0) {
+ my ( $self, $c ) = @_;
$self->update_or_create($c);
}
=cut
-sub delete_bulk :Chained('objects_no_id') :PathPart('delete') :Args(0)
-{
- my ($self, $c) = @_;
+sub delete_bulk : Chained('objects_no_id') : PathPart('delete') : Args(0) {
+ my ( $self, $c ) = @_;
$self->delete($c);
}
use namespace::autoclean;
#XXX HACK to satisfy the used roles requirements
-# see Moose test 600_todo_tests/006_required_role_accessors.t
-sub _application {}
-sub _controller {}
+# see Moose test todo_tests/required_role_accessors.t
+sub _application { }
+sub _controller { }
=attribute_private _application is: ro, isa: Object|ClassName, handles: Catalyst::Controller::DBIC::API::StoredResultSource
=cut
-has '_application' =>
-(
- is => 'ro',
+has '_application' => (
+ is => 'ro',
writer => '_set_application',
- isa => Object|ClassName,
+ isa => Object | ClassName,
);
-has '_controller' =>
-(
- is => 'ro',
- writer => '_set_controller',
- isa => Object,
- trigger => sub
- {
- my ($self, $new) = @_;
-
- $self->_set_class($new->class) if defined($new->class);
- $self->_set_application($new->_application);
- $self->_set_search_exposes($new->search_exposes);
- $self->_set_select_exposes($new->select_exposes);
+has '_controller' => (
+ is => 'ro',
+ writer => '_set_controller',
+ isa => Object,
+ trigger => sub {
+ my ( $self, $new ) = @_;
+
+ $self->_set_class( $new->class ) if defined( $new->class );
+ $self->_set_application( $new->_application );
+ $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';
+ 'Catalyst::Controller::DBIC::API::RequestArguments',
+ 'Catalyst::Controller::DBIC::API::Request::Context';
=head1 DESCRIPTION
use Catalyst::Controller::DBIC::API::Types(':all');
use namespace::autoclean;
-=attribute_public objects is: ro, isa ArrayRef[Tuple[Object,Maybe[HashRef]]], traits: ['Array']
+=attribute_public objects is:
+ ro
+ isa ArrayRef[Tuple[Object,Maybe[HashRef]]]
+ traits: ['Array']
-This attribute stores the objects found/created at the object action. It handles the following methods:
+This attribute stores the objects found/created at the object action.
+It handles the following methods:
- all_objects => 'elements'
- add_object => 'push'
+ all_objects => 'elements'
+ add_object => 'push'
count_objects => 'count'
- has_objects => 'count'
+ has_objects => 'count'
clear_objects => 'clear'
=cut
-has objects =>
-(
- is => 'ro',
- isa => ArrayRef[ Tuple[ Object, Maybe[HashRef] ] ],
- traits => [ 'Array' ],
+has objects => (
+ is => 'ro',
+ isa => ArrayRef[Tuple[Object,Maybe[HashRef]]],
+ traits => ['Array'],
default => sub { [] },
- handles =>
- {
- all_objects => 'elements',
- add_object => 'push',
+ handles => {
+ all_objects => 'elements',
+ add_object => 'push',
count_objects => 'count',
- has_objects => 'count',
+ has_objects => 'count',
clear_objects => 'clear',
- get_object => 'get',
+ get_object => 'get',
},
);
-=attribute_public current_result_set is: ro, isa: L<Catalyst::Controller::DBIC::API::Types/ResultSet>
+=attribute_public current_result_set is:
+ ro
+ isa: L<Catalyst::Controller::DBIC::API::Types/ResultSet>
-Stores the current ResultSet derived from the initial L<Catalyst::Controller::DBIC::API::StoredResultSource/stored_model>.
+Stores the current ResultSet derived from the initial
+L<Catalyst::Controller::DBIC::API::StoredResultSource/stored_model>.
=cut
-has current_result_set =>
-(
- is => 'ro',
- isa => ResultSet,
+has current_result_set => (
+ is => 'ro',
+ isa => ResultSet,
writer => '_set_current_result_set',
);
=cut
has [qw( search_validator select_validator )] => (
- is => 'ro',
- isa => 'Catalyst::Controller::DBIC::API::Validator',
- lazy => 1,
+ is => 'ro',
+ isa => 'Catalyst::Controller::DBIC::API::Validator',
+ lazy => 1,
builder => '_build_validator',
);
parameter static => ( isa => Bool, default => 0 );
role {
-
my $p = shift;
- if($p->static)
- {
- requires qw/check_has_relation check_column_relation prefetch_allows /;
+ if ( $p->static ) {
+ requires
+ qw( check_has_relation check_column_relation prefetch_allows );
}
- else
- {
- requires qw/_controller check_has_relation check_column_relation/;
+ else {
+ requires qw( _controller check_has_relation check_column_relation );
}
=attribute_public count is: ro, isa: Int
=cut
- has 'count' =>
- (
- is => 'ro',
- writer => '_set_count',
- isa => Int,
+ has 'count' => (
+ is => 'ro',
+ writer => '_set_count',
+ isa => Int,
predicate => 'has_count',
);
=cut
- has 'page' =>
- (
- is => 'ro',
- writer => '_set_page',
- isa => Int,
+ has 'page' => (
+ is => 'ro',
+ writer => '_set_page',
+ isa => Int,
predicate => 'has_page',
);
=cut
- has 'offset' =>
- (
- is => 'ro',
- writer => '_set_offset',
- isa => Int,
+ has 'offset' => (
+ is => 'ro',
+ writer => '_set_offset',
+ isa => Int,
predicate => 'has_offset',
);
=cut
- has 'ordered_by' =>
- (
- is => 'ro',
- writer => '_set_ordered_by',
- isa => OrderedBy,
+ has 'ordered_by' => (
+ is => 'ro',
+ writer => '_set_ordered_by',
+ isa => OrderedBy,
predicate => 'has_ordered_by',
- coerce => 1,
- default => sub { $p->static ? [] : undef },
+ coerce => 1,
+ default => sub { $p->static ? [] : undef },
);
=attribute_public groupd_by is: ro, isa: L<Catalyst::Controller::DBIC::API::Types/GroupedBy>
=cut
- has 'grouped_by' =>
- (
- is => 'ro',
- writer => '_set_grouped_by',
- isa => GroupedBy,
+ has 'grouped_by' => (
+ is => 'ro',
+ writer => '_set_grouped_by',
+ isa => GroupedBy,
predicate => 'has_grouped_by',
- coerce => 1,
- default => sub { $p->static ? [] : undef },
+ coerce => 1,
+ default => sub { $p->static ? [] : undef },
);
=attribute_public prefetch is: ro, isa: L<Catalyst::Controller::DBIC::API::Types/Prefetch>
=cut
- has prefetch =>
- (
- is => 'ro',
- writer => '_set_prefetch',
- isa => Prefetch,
+ has prefetch => (
+ is => 'ro',
+ writer => '_set_prefetch',
+ isa => Prefetch,
default => sub { $p->static ? [] : undef },
- coerce => 1,
- trigger => sub
- {
- my ($self, $new) = @_;
-
- foreach my $pf (@$new)
- {
- if(HashRef->check($pf))
- {
- die qq|'${\Dumper($pf)}' is not an allowed prefetch in: ${\join("\n", @{$self->prefetch_validator->templates})}|
+ coerce => 1,
+ trigger => sub {
+ my ( $self, $new ) = @_;
+
+ 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 {
+ die
+ qq|'$pf' is not an allowed prefetch in: ${\join("\n", @{$self->prefetch_validator->templates})}|
+ unless $self->prefetch_validator->validate(
+ { $pf => 1 } )->[0];
}
}
},
=cut
- has 'search_exposes' =>
- (
- is => 'ro',
- writer => '_set_search_exposes',
- isa => ArrayRef[Str|HashRef],
+ has 'search_exposes' => (
+ is => 'ro',
+ writer => '_set_search_exposes',
+ isa => ArrayRef [ Str | HashRef ],
predicate => 'has_search_exposes',
- default => sub { [ ] },
- trigger => sub
- {
- my ($self, $new) = @_;
+ default => sub { [] },
+ trigger => sub {
+ my ( $self, $new ) = @_;
$self->search_validator->load($_) for @$new;
},
);
=cut
- has 'search' =>
- (
- is => 'ro',
- writer => '_set_search',
- isa => SearchParameters,
+ has 'search' => (
+ is => 'ro',
+ writer => '_set_search',
+ isa => SearchParameters,
predicate => 'has_search',
- coerce => 1,
- trigger => sub
- {
- my ($self, $new) = @_;
+ coerce => 1,
+ trigger => sub {
+ my ( $self, $new ) = @_;
- if($self->has_search_exposes and @{$self->search_exposes})
- {
- foreach my $foo (@$new)
- {
- while( my ($k, $v) = each %$foo)
- {
+ if ( $self->has_search_exposes and @{ $self->search_exposes } ) {
+ foreach my $foo (@$new) {
+ while ( my ( $k, $v ) = each %$foo ) {
local $Data::Dumper::Terse = 1;
- die qq|{ $k => ${\Dumper($v)} } is not an allowed search term in: ${\join("\n", @{$self->search_validator->templates})}|
- unless $self->search_validator->validate({$k=>$v})->[0];
+ die
+ qq|{ $k => ${\Dumper($v)} } is not an allowed search term in: ${\join("\n", @{$self->search_validator->templates})}|
+ unless $self->search_validator->validate(
+ { $k => $v } )->[0];
}
}
}
- else
- {
- foreach my $foo (@$new)
- {
- while( my ($k, $v) = each %$foo)
- {
- $self->check_column_relation({$k => $v});
+ else {
+ foreach my $foo (@$new) {
+ while ( my ( $k, $v ) = each %$foo ) {
+ $self->check_column_relation( { $k => $v } );
}
}
}
- my ($search_parameters, $search_attributes) = $self->generate_parameters_attributes($new);
+ my ( $search_parameters, $search_attributes ) =
+ $self->generate_parameters_attributes($new);
$self->_set_search_parameters($search_parameters);
$self->_set_search_attributes($search_attributes);
=cut
- has search_parameters =>
- (
- is => 'ro',
- isa => SearchParameters,
- writer => '_set_search_parameters',
+ has search_parameters => (
+ is => 'ro',
+ isa => SearchParameters,
+ writer => '_set_search_parameters',
predicate => 'has_search_parameters',
- coerce => 1,
- default => sub { [{}] },
+ coerce => 1,
+ default => sub { [ {} ] },
);
=attribute_public search_attributes is:ro, isa: HashRef
=cut
- has search_attributes =>
- (
- is => 'ro',
- isa => HashRef,
- writer => '_set_search_attributes',
- predicate => 'has_search_attributes',
+ has search_attributes => (
+ is => 'ro',
+ isa => HashRef,
+ writer => '_set_search_attributes',
+ predicate => 'has_search_attributes',
lazy_build => 1,
);
=cut
- has search_total_entries =>
- (
- is => 'ro',
- isa => Int,
- writer => '_set_search_total_entries',
+ has search_total_entries => (
+ is => 'ro',
+ isa => Int,
+ writer => '_set_search_total_entries',
predicate => 'has_search_total_entries',
);
=cut
- has 'select_exposes' =>
- (
- is => 'ro',
- writer => '_set_select_exposes',
- isa => ArrayRef[Str|HashRef],
+ has 'select_exposes' => (
+ is => 'ro',
+ writer => '_set_select_exposes',
+ isa => ArrayRef [ Str | HashRef ],
predicate => 'has_select_exposes',
- default => sub { [ ] },
- trigger => sub
- {
- my ($self, $new) = @_;
+ default => sub { [] },
+ trigger => sub {
+ my ( $self, $new ) = @_;
$self->select_validator->load($_) for @$new;
},
);
=cut
- has select =>
- (
- is => 'ro',
- writer => '_set_select',
- isa => SelectColumns,
+ has select => (
+ is => 'ro',
+ writer => '_set_select',
+ isa => SelectColumns,
predicate => 'has_select',
- default => sub { $p->static ? [] : undef },
- coerce => 1,
- trigger => sub
- {
- my ($self, $new) = @_;
- if($self->has_select_exposes)
- {
- foreach my $val (@$new)
- {
+ default => sub { $p->static ? [] : undef },
+ coerce => 1,
+ trigger => sub {
+ my ( $self, $new ) = @_;
+ if ( $self->has_select_exposes ) {
+ foreach my $val (@$new) {
die "'$val' is not allowed in a select"
unless $self->select_validator->validate($val);
}
}
- else
- {
- $self->check_column_relation($_, $p->static) for @$new;
+ else {
+ $self->check_column_relation( $_, $p->static ) for @$new;
}
},
);
=cut
- has as =>
- (
- is => 'ro',
- writer => '_set_as',
- isa => AsAliases,
+ has as => (
+ is => 'ro',
+ writer => '_set_as',
+ isa => AsAliases,
default => sub { $p->static ? [] : undef },
- trigger => sub
- {
- my ($self, $new) = @_;
- if($self->has_select)
- {
- die "'as' argument count (${\scalar(@$new)}) must match 'select' argument count (${\scalar(@{$self->select || []})})"
- unless @$new == @{$self->select || []};
+ trigger => sub {
+ my ( $self, $new ) = @_;
+ if ( $self->has_select ) {
+ die
+ "'as' argument count (${\scalar(@$new)}) must match 'select' argument count (${\scalar(@{$self->select || []})})"
+ unless @$new == @{ $self->select || [] };
}
- elsif(defined $new)
- {
+ elsif ( defined $new ) {
die "'as' is only valid if 'select is also provided'";
}
}
=cut
- has joins =>
- (
- is => 'ro',
- isa => JoinBuilder,
+ has joins => (
+ is => 'ro',
+ isa => JoinBuilder,
lazy_build => 1,
- handles =>
- {
- build_joins => 'joins',
- }
+ handles => { build_joins => 'joins', }
);
=attribute_public request_data is: ro, isa: HashRef
=cut
- has 'request_data' =>
- (
- is => 'ro',
- isa => HashRef,
- writer => '_set_request_data',
+ has 'request_data' => (
+ is => 'ro',
+ isa => HashRef,
+ writer => '_set_request_data',
predicate => 'has_request_data',
- trigger => sub
- {
- my ($self, $new) = @_;
+ trigger => sub {
+ my ( $self, $new ) = @_;
my $controller = $self->_controller;
return unless defined($new) && keys %$new;
- $self->_set_prefetch($new->{$controller->prefetch_arg}) if exists $new->{$controller->prefetch_arg};
- $self->_set_select($new->{$controller->select_arg}) if exists $new->{$controller->select_arg};
- $self->_set_as($new->{$controller->as_arg}) if exists $new->{$controller->as_arg};
- $self->_set_grouped_by($new->{$controller->grouped_by_arg}) if exists $new->{$controller->grouped_by_arg};
- $self->_set_ordered_by($new->{$controller->ordered_by_arg}) if exists $new->{$controller->ordered_by_arg};
- $self->_set_count($new->{$controller->count_arg}) if exists $new->{$controller->count_arg};
- $self->_set_page($new->{$controller->page_arg}) if exists $new->{$controller->page_arg};
- $self->_set_offset($new->{$controller->offset_arg}) if exists $new->{$controller->offset_arg};
- $self->_set_search($new->{$controller->search_arg}) if exists $new->{$controller->search_arg};
+ $self->_set_prefetch( $new->{ $controller->prefetch_arg } )
+ if exists $new->{ $controller->prefetch_arg };
+ $self->_set_select( $new->{ $controller->select_arg } )
+ if exists $new->{ $controller->select_arg };
+ $self->_set_as( $new->{ $controller->as_arg } )
+ if exists $new->{ $controller->as_arg };
+ $self->_set_grouped_by( $new->{ $controller->grouped_by_arg } )
+ if exists $new->{ $controller->grouped_by_arg };
+ $self->_set_ordered_by( $new->{ $controller->ordered_by_arg } )
+ if exists $new->{ $controller->ordered_by_arg };
+ $self->_set_count( $new->{ $controller->count_arg } )
+ if exists $new->{ $controller->count_arg };
+ $self->_set_page( $new->{ $controller->page_arg } )
+ if exists $new->{ $controller->page_arg };
+ $self->_set_offset( $new->{ $controller->offset_arg } )
+ if exists $new->{ $controller->offset_arg };
+ $self->_set_search( $new->{ $controller->search_arg } )
+ if exists $new->{ $controller->search_arg };
}
);
- method _build_joins => sub { return Catalyst::Controller::DBIC::API::JoinBuilder->new(name => 'TOP') };
+ method _build_joins => sub {
+ return Catalyst::Controller::DBIC::API::JoinBuilder->new(
+ name => 'TOP' );
+ };
=method_protected format_search_parameters
=cut
- method format_search_parameters => sub
- {
- my ($self, $params) = @_;
+ method format_search_parameters => sub {
+ my ( $self, $params ) = @_;
my $genparams = [];
- foreach my $param (@$params)
- {
- push(@$genparams, $self->generate_column_parameters($self->stored_result_source, $param, $self->joins));
+ foreach my $param (@$params) {
+ push(
+ @$genparams,
+ $self->generate_column_parameters(
+ $self->stored_result_source,
+ $param, $self->joins
+ )
+ );
}
return $genparams;
=cut
- method generate_column_parameters => sub
- {
- my ($self, $source, $param, $join, $base) = @_;
+ method generate_column_parameters => sub {
+ my ( $self, $source, $param, $join, $base ) = @_;
$base ||= 'me';
my $search_params = {};
# build up condition
- foreach my $column (keys %$param)
- {
- if ($source->has_relationship($column))
- {
+ foreach my $column ( keys %$param ) {
+ if ( $source->has_relationship($column) ) {
+
# check if the value isn't a hashref
- unless (ref($param->{$column}) && reftype($param->{$column}) eq 'HASH')
+ unless ( ref( $param->{$column} )
+ && reftype( $param->{$column} ) eq 'HASH' )
{
- $search_params->{join('.', $base, $column)} = $param->{$column};
+ $search_params->{ join( '.', $base, $column ) } =
+ $param->{$column};
next;
}
- $search_params = { %$search_params, %{
- $self->generate_column_parameters
- (
- $source->related_source($column),
- $param->{$column},
- Catalyst::Controller::DBIC::API::JoinBuilder->new(parent => $join, name => $column),
- $column
- )
- }};
+ $search_params = {
+ %$search_params,
+ %{ $self->generate_column_parameters(
+ $source->related_source($column),
+ $param->{$column},
+ Catalyst::Controller::DBIC::API::JoinBuilder->new(
+ parent => $join,
+ name => $column
+ ),
+ $column
+ )
+ }
+ };
}
- elsif ($source->has_column($column))
- {
- $search_params->{join('.', $base, $column)} = $param->{$column};
+ elsif ( $source->has_column($column) ) {
+ $search_params->{ join( '.', $base, $column ) } =
+ $param->{$column};
}
+
# might be a sql function instead of a column name
# e.g. {colname => {like => '%foo%'}}
- else
- {
+ else {
# but only if it's not a hashref
- unless (ref($param->{$column}) && reftype($param->{$column}) eq 'HASH') {
- $search_params->{join('.', $base, $column)} = $param->{$column};
+ unless ( ref( $param->{$column} )
+ && reftype( $param->{$column} ) eq 'HASH' )
+ {
+ $search_params->{ join( '.', $base, $column ) } =
+ $param->{$column};
}
else {
die "$column is neither a relationship nor a column\n";
=cut
- method generate_parameters_attributes => sub
- {
- my ($self, $args) = @_;
+ method generate_parameters_attributes => sub {
+ my ( $self, $args ) = @_;
- return ( $self->format_search_parameters($args), $self->search_attributes );
+ return ( $self->format_search_parameters($args),
+ $self->search_attributes );
};
=method_protected _build_search_attributes
=cut
- method _build_search_attributes => sub
- {
- my ($self, $args) = @_;
- my $static = $self->_controller;
- my $search_attributes =
- {
- group_by => $self->grouped_by || ((scalar(@{$static->grouped_by})) ? $static->grouped_by : undef),
- order_by => $self->ordered_by || ((scalar(@{$static->ordered_by})) ? $static->ordered_by : undef),
- select => $self->select || ((scalar(@{$static->select})) ? $static->select : undef),
- as => $self->as || ((scalar(@{$static->as})) ? $static->as : undef),
+ method _build_search_attributes => sub {
+ my ( $self, $args ) = @_;
+ my $static = $self->_controller;
+ my $search_attributes = {
+ group_by => $self->grouped_by
+ || (
+ ( scalar( @{ $static->grouped_by } ) ) ? $static->grouped_by
+ : undef
+ ),
+ order_by => $self->ordered_by
+ || (
+ ( scalar( @{ $static->ordered_by } ) ) ? $static->ordered_by
+ : undef
+ ),
+ select => $self->select
+ || (
+ ( scalar( @{ $static->select } ) ) ? $static->select
+ : undef
+ ),
+ as => $self->as
+ || ( ( scalar( @{ $static->as } ) ) ? $static->as : undef ),
prefetch => $self->prefetch || $static->prefetch || undef,
- rows => $self->count || $static->count,
- page => $static->page,
- offset => $self->offset,
- join => $self->build_joins,
+ rows => $self->count || $static->count,
+ page => $static->page,
+ offset => $self->offset,
+ join => $self->build_joins,
};
- if($self->has_page)
- {
+ if ( $self->has_page ) {
$search_attributes->{page} = $self->page;
}
- elsif(!$self->has_page && defined($search_attributes->{offset}) && defined($search_attributes->{rows}))
+ elsif (!$self->has_page
+ && defined( $search_attributes->{offset} )
+ && defined( $search_attributes->{rows} ) )
{
- $search_attributes->{page} = $search_attributes->{offset} / $search_attributes->{rows} + 1;
+ $search_attributes->{page} =
+ $search_attributes->{offset} / $search_attributes->{rows} + 1;
delete $search_attributes->{offset};
}
-
- $search_attributes =
- {
- map { @$_ }
- grep
- {
- defined($_->[1])
- ?
- (ref($_->[1]) && reftype($_->[1]) eq 'HASH' && keys %{$_->[1]})
- || (ref($_->[1]) && reftype($_->[1]) eq 'ARRAY' && @{$_->[1]})
- || length($_->[1])
- :
- undef
- }
- map { [$_, $search_attributes->{$_}] }
- keys %$search_attributes
+ $search_attributes = {
+ map {@$_}
+ grep {
+ defined( $_->[1] )
+ ? ( ref( $_->[1] )
+ && reftype( $_->[1] ) eq 'HASH'
+ && keys %{ $_->[1] } )
+ || ( ref( $_->[1] )
+ && reftype( $_->[1] ) eq 'ARRAY'
+ && @{ $_->[1] } )
+ || length( $_->[1] )
+ : undef
+ }
+ map { [ $_, $search_attributes->{$_} ] }
+ keys %$search_attributes
};
-
- if ($search_attributes->{page} && !$search_attributes->{rows}) {
+ if ( $search_attributes->{page} && !$search_attributes->{rows} ) {
die 'list_page can only be used with list_count';
}
- if ($search_attributes->{select}) {
+ if ( $search_attributes->{select} ) {
+
# make sure all columns have an alias to avoid ambiguous issues
# but allow non strings (eg. hashrefs for db procs like 'count')
# to pass through unmolested
- $search_attributes->{select} = [map { (Str->check($_) && $_ !~ m/\./) ? "me.$_" : $_ } (ref $search_attributes->{select}) ? @{$search_attributes->{select}} : $search_attributes->{select}];
+ $search_attributes->{select} = [
+ map { ( Str->check($_) && $_ !~ m/\./ ) ? "me.$_" : $_ }
+ ( ref $search_attributes->{select} )
+ ? @{ $search_attributes->{select} }
+ : $search_attributes->{select}
+ ];
}
return $search_attributes;
};
};
+
=head1 DESCRIPTION
-RequestArguments embodies those arguments that are provided as part of a request or effect validation on request arguments. This Role can be consumed in one of two ways. As this is a parameterized Role, it accepts a single argument at composition time: 'static'. This indicates that those parameters should be stored statically and used as a fallback when the current request doesn't provide them.
+RequestArguments embodies those arguments that are provided as part of a request
+or effect validation on request arguments. This Role can be consumed in one of
+two ways. As this is a parameterized Role, it accepts a single argument at
+composition time: 'static'. This indicates that those parameters should be
+stored statically and used as a fallback when the current request doesn't
+provide them.
=cut
-
1;
=cut
-foreach my $var (qw/create_requires create_allows update_requires update_allows/)
+foreach my $var (
+ qw( create_requires create_allows update_requires update_allows ))
{
- has $var =>
- (
- is => 'ro',
- isa => ArrayRef[Str|HashRef],
- traits => ['Array'],
+ has $var => (
+ is => 'ro',
+ isa => ArrayRef [ Str | HashRef ],
+ traits => ['Array'],
default => sub { [] },
- trigger => sub
- {
- my ($self, $new) = @_;
- $self->check_column_relation($_, 1) for @$new;
+ trigger => sub {
+ my ( $self, $new ) = @_;
+ $self->check_column_relation( $_, 1 ) for @$new;
},
- handles =>
- {
- "get_${var}_column" => 'get',
- "set_${var}_column" => 'set',
+ handles => {
+ "get_${var}_column" => 'get',
+ "set_${var}_column" => 'set',
"delete_${var}_column" => 'delete',
"insert_${var}_column" => 'insert',
- "count_${var}_column" => 'count',
- "all_${var}_columns" => 'elements',
+ "count_${var}_column" => 'count',
+ "all_${var}_columns" => 'elements',
}
);
- before "set_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) };
- before "insert_${var}_column" => sub { $_[0]->check_column_relation($_[2], 1) };
+ before "set_${var}_column" =>
+ sub { $_[0]->check_column_relation( $_[2], 1 ) };
+ before "insert_${var}_column" =>
+ sub { $_[0]->check_column_relation( $_[2], 1 ) };
}
=attribute_public prefetch_allows is: ro, isa: ArrayRef[ArrayRef|Str|HashRef]
=cut
has 'prefetch_allows' => (
- is => 'ro',
- writer => '_set_prefetch_allows',
- isa => ArrayRef[ArrayRef|Str|HashRef],
- default => sub { [ ] },
+ is => 'ro',
+ writer => '_set_prefetch_allows',
+ isa => ArrayRef [ ArrayRef | Str | HashRef ],
+ default => sub { [] },
predicate => 'has_prefetch_allows',
- traits => ['Array'],
- handles =>
- {
- all_prefetch_allows => 'elements',
- },
+ traits => ['Array'],
+ handles => { all_prefetch_allows => 'elements', },
);
has 'prefetch_validator' => (
- is => 'ro',
- isa => 'Catalyst::Controller::DBIC::API::Validator',
+ is => 'ro',
+ isa => 'Catalyst::Controller::DBIC::API::Validator',
lazy_build => 1,
);
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);
+ 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);
+ 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);
+ 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);
+ foreach my $rel ( $self->all_prefetch_allows ) {
+ _check_rel( $self, $rel, 1, $validator );
}
return $validator;
=cut
-has 'grouped_by_arg' => ( is => 'ro', isa => Str, default => 'list_grouped_by' );
+has 'grouped_by_arg' =>
+ ( is => 'ro', isa => Str, default => 'list_grouped_by' );
=attribute_public ordered_by_arg is: ro, isa: Str, default: 'list_ordered_by'
=cut
-has 'ordered_by_arg' => ( is => 'ro', isa => Str, default => 'list_ordered_by' );
+has 'ordered_by_arg' =>
+ ( is => 'ro', isa => Str, default => 'list_ordered_by' );
=attribute_public prefetch_arg is: ro, isa: Str, default: 'list_prefetch'
=cut
-has 'stash_key' => ( is => 'ro', isa => Str, default => 'response');
+has 'stash_key' => ( is => 'ro', isa => Str, default => 'response' );
=attribute_public data_root is: ro, isa: Str, default: 'list'
=cut
-has 'data_root' => ( is => 'ro', isa => Str, default => 'list');
+has 'data_root' => ( is => 'ro', isa => Str, default => 'list' );
=attribute_public item_root is: ro, isa: Str, default: 'data'
=cut
-has 'item_root' => ( is => 'ro', isa => Str, default => 'data');
+has 'item_root' => ( is => 'ro', isa => Str, default => 'data' );
=attribute_public total_entries_arg is: ro, isa: Str, default: 'totalcount'
=cut
-has 'total_entries_arg' => ( is => 'ro', isa => Str, default => 'totalcount' );
+has 'total_entries_arg' =>
+ ( is => 'ro', isa => Str, default => 'totalcount' );
=attribute_public use_json_boolean is: ro, isa: Bool, default: 0
package Catalyst::Controller::DBIC::API::StoredResultSource;
+
#ABSTRACT: Provides accessors for static resources
use Moose::Role;
=cut
-has 'result_class' => ( is => 'ro', isa => Maybe[Str], default => 'DBIx::Class::ResultClass::HashRefInflator' );
+has 'result_class' => (
+ is => 'ro',
+ isa => Maybe [Str],
+ default => 'DBIx::Class::ResultClass::HashRefInflator'
+);
=method_public stored_result_source
=cut
-sub stored_result_source
-{
+sub stored_result_source {
return shift->stored_model->result_source;
}
=cut
-sub stored_model
-{
- return $_[0]->_application->model($_[0]->class);
+sub stored_model {
+ return $_[0]->_application->model( $_[0]->class );
}
=method_public check_has_column
=cut
-sub check_has_column
-{
- my ($self, $col) = @_;
+sub check_has_column {
+ my ( $self, $col ) = @_;
die "Column '$col' does not exist in ResultSet '${\$self->class}'"
unless $self->stored_result_source->has_column($col);
}
=method_public check_has_relation
-check_has_relation meticulously delves into the result sources relationships to determine if the provided relation is valid. Accepts a relation name, and optional HashRef indicating a nested relationship. Iterates, and recurses through provided arguments until exhausted. Dies if at any time the relationship or column does not exist.
+check_has_relation meticulously delves into the result sources relationships to
+determine if the provided relation is valid.
+Accepts a relation name, an optional HashRef indicating a nested relationship.
+Iterates and recurses through provided arguments until exhausted.
+Dies if at any time the relationship or column does not exist.
=cut
-sub check_has_relation
-{
- my ($self, $rel, $other, $nest, $static) = @_;
+sub check_has_relation {
+ my ( $self, $rel, $other, $nest, $static ) = @_;
$nest ||= $self->stored_result_source;
- if(HashRef->check($other))
- {
+ if ( HashRef->check($other) ) {
my $rel_src = $nest->related_source($rel);
die "Relation '$rel_src' does not exist" if not defined($rel_src);
- while(my($k,$v) = each %$other)
- {
- $self->check_has_relation($k, $v, $rel_src, $static);
+ while ( my ( $k, $v ) = each %$other ) {
+ $self->check_has_relation( $k, $v, $rel_src, $static );
}
}
- else
- {
+ else {
return 1 if $static && ArrayRef->check($other) && $other->[0] eq '*';
die "Relation '$rel' does not exist in ${\$nest->from}"
unless $nest->has_relationship($rel) || $nest->has_column($rel);
=method_public check_column_relation
-Convenience method to first check if the provided argument is a valid relation (if it is a HashRef) or column.
+Convenience method to first check if the provided argument is a valid relation
+(if it is a HashRef) or column.
=cut
-sub check_column_relation
-{
- my ($self, $col_rel, $static) = @_;
-
- if(HashRef->check($col_rel))
- {
- try
- {
- while(my($k,$v) = each %$col_rel)
- {
- $self->check_has_relation($k, $v, undef, $static);
+sub check_column_relation {
+ my ( $self, $col_rel, $static ) = @_;
+
+ if ( HashRef->check($col_rel) ) {
+ try {
+ while ( my ( $k, $v ) = each %$col_rel ) {
+ $self->check_has_relation( $k, $v, undef, $static );
}
}
- catch
- {
+ catch {
# not a relation but a column with a predicate
- while(my($k, undef) = each %$col_rel)
- {
+ while ( my ( $k, undef ) = each %$col_rel ) {
$self->check_has_column($k);
}
}
}
- else
- {
+ else {
$self->check_has_column($col_rel);
}
}
use warnings;
use strict;
-use MooseX::Types -declare => [qw/OrderedBy GroupedBy Prefetch SelectColumns AsAliases ResultSource ResultSet Model SearchParameters JoinBuilder/];
+use MooseX::Types -declare => [
+ qw( OrderedBy GroupedBy Prefetch SelectColumns AsAliases ResultSource
+ ResultSet Model SearchParameters JoinBuilder )
+];
use MooseX::Types::Moose(':all');
=type Prefetch as Maybe[ArrayRef[Str|HashRef]]
=cut
-subtype JoinBuilder, as class_type('Catalyst::Controller::DBIC::API::JoinBuilder');
+subtype JoinBuilder,
+ as class_type('Catalyst::Controller::DBIC::API::JoinBuilder');
=type Model as class_type('DBIx::Class')
package Catalyst::Controller::DBIC::API::Validator;
+
#ABSTRACT: Provides validation services for inbound requests against whitelisted parameters
use Moose;
use Catalyst::Controller::DBIC::API::Validator::Visitor;
has '+visitor' => ( 'builder' => '_build_custom_visitor' );
-sub _build_custom_visitor
-{
+sub _build_custom_visitor {
return Catalyst::Controller::DBIC::API::Validator::Visitor->new();
}
__PACKAGE__->meta->make_immutable;
-1;
\ No newline at end of file
+1;
package Catalyst::Controller::DBIC::API::Validator::Visitor;
+
#ABSTRACT: Provides validation services for inbound requests against whitelisted parameters
use Moose;
use namespace::autoclean;
use constant DEBUG => $ENV{DATA_DPATH_VALIDATOR_DEBUG} || 0;
-around visit_array => sub
-{
- my ($orig, $self, $array) = @_;
+around visit_array => sub {
+ my ( $orig, $self, $array ) = @_;
$self->dive();
- warn 'ARRAY: '. $self->current_template if DEBUG;
- if(@$array == 1 && $array->[0] eq '*')
- {
+ warn 'ARRAY: ' . $self->current_template if DEBUG;
+ if ( @$array == 1 && $array->[0] eq '*' ) {
$self->append_text('[reftype eq "HASH" ]');
- $self->add_template($self->current_template);
+ $self->add_template( $self->current_template );
}
- else
- {
- if($self->current_template =~ /\/$/)
- {
+ else {
+ if ( $self->current_template =~ /\/$/ ) {
my $temp = $self->current_template;
$self->reset_template();
$temp =~ s/\/$//;
$self->rise();
};
-sub visit_array_entry
-{
+sub visit_array_entry {
+
# to make release-unused-vars.t happy
#my ($self, $elem, $index, $array) = @_;
- my ($self, $elem) = @_;
+ my ( $self, $elem ) = @_;
$self->dive();
- warn 'ARRAYENTRY: '. $self->current_template if DEBUG;
- if(!ref($elem))
- {
- $self->append_text($elem . '/*');
- $self->add_template($self->current_template);
+ warn 'ARRAYENTRY: ' . $self->current_template if DEBUG;
+ if ( !ref($elem) ) {
+ $self->append_text( $elem . '/*' );
+ $self->add_template( $self->current_template );
}
- elsif(ref($elem) eq 'HASH')
- {
+ elsif ( ref($elem) eq 'HASH' ) {
$self->visit($elem);
}
$self->rise();
$self->value_type('NONE');
-};
+}
-around visit_hash => sub
-{
- my ($orig, $self, $hash) = @_;
+around visit_hash => sub {
+ my ( $orig, $self, $hash ) = @_;
$self->dive();
- if($self->current_template =~ /\/$/)
- {
+ if ( $self->current_template =~ /\/$/ ) {
my $temp = $self->current_template;
$self->reset_template();
$temp =~ s/\/$//;
$self->append_text($temp);
}
- warn 'HASH: '. $self->current_template if DEBUG;
+ warn 'HASH: ' . $self->current_template if DEBUG;
$self->$orig($hash);
$self->rise();
};
-around visit_value => sub
-{
- my ($orig, $self, $val) = @_;
+around visit_value => sub {
+ my ( $orig, $self, $val ) = @_;
- if($self->value_type eq 'NONE')
- {
+ if ( $self->value_type eq 'NONE' ) {
$self->dive();
- $self->append_text($val . '/*');
- $self->add_template($self->current_template);
+ $self->append_text( $val . '/*' );
+ $self->add_template( $self->current_template );
warn 'VALUE: ' . $self->current_template if DEBUG;
$self->rise();
}
- elsif($self->value_type eq 'HashKey')
- {
+ elsif ( $self->value_type eq 'HashKey' ) {
$self->append_text($val);
warn 'VALUE: ' . $self->current_template if DEBUG;
}
- else
- {
+ else {
$self->$orig($val);
}
};
-
__PACKAGE__->meta->make_immutable;
-1;
\ No newline at end of file
+1;