Skip Menu |

This queue is for tickets about the Catalyst-Controller-DBIC-API CPAN distribution.

Report information
The Basics
Id: 63686
Status: resolved
Priority: 0/
Queue: Catalyst-Controller-DBIC-API

People
Owner: abraxxa [...] cpan.org
Requestors: cub.uanic [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: 2.002004



Subject: Two improvements
Two improvements First patch add possibility to tweak resultset class after search was made. This could be needed, because with DBIx::Class::ResultClass::HashRefInflator it's not possible to access row-level data and methods in row_format_output(). Model class can have some method to generate custom data, and it will be not accessible without one more query to DB per each row. Second patch is about adding support for tweaking place in stash, where response should be stored. Sources for ::REST and ::RPC both have 'stash_key' config option, but this is only place I can see it. Seems, this option is not really used, and 'response' value is hard-coded. This patch make this configurable.
Subject: 0002-Added-support-for-tweaking-where-to-store-response-i.patch
From 478925eb3219d0e2043cf53f6877f61e868bd8db Mon Sep 17 00:00:00 2001 From: Oleg Kostyuk <cub.uanic@gmail.com> Date: Tue, 7 Dec 2010 01:28:08 +0200 Subject: [PATCH] Added support for tweaking where to store response in stash --- lib/Catalyst/Controller/DBIC/API.pm | 28 +++++++++++-------- .../Controller/DBIC/API/StaticArguments.pm | 8 +++++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/Catalyst/Controller/DBIC/API.pm b/lib/Catalyst/Controller/DBIC/API.pm index 2753a74..2a72e28 100644 --- a/lib/Catalyst/Controller/DBIC/API.pm +++ b/lib/Catalyst/Controller/DBIC/API.pm @@ -332,7 +332,7 @@ sub object_lookup list's steps are broken up into three distinct methods: L</list_munge_parameters>, L</list_perform_search>, and L</list_format_output>. -The goal of this method is to call ->search() on the current_result_set, change resultset class of the result (if needed), and return it in $c->stash->{response}->{$self->data_root}. Please see the individual methods for more details on what actual processing takes place. +The goal of this method is to call ->search() on the current_result_set, change resultset class of the result (if needed), and return it in $c->stash->{$self->stash_key}->{$self->data_root}. Please see the individual methods for more details on what actual processing takes place. If the L</select> config param is defined then the hashes will contain only those columns, otherwise all columns in the object will be returned. L</select> of course supports the function/procedure calling semantics that L<DBIx::Class::ResultSet/select>. In order to have proper column names in the result, provide arguments in L</as> (which also follows L<DBIx::Class::ResultSet/as> semantics. Similarly L</count>, L</page>, L</grouped_by> and L</ordered_by> affect the maximum number of rows returned as well as the ordering and grouping. Note that if select, count, ordered_by or grouped_by request parameters are present then these will override the values set on the class with select becoming bound by the select_exposes attribute. @@ -446,7 +446,7 @@ sub list_format_output $output->{$self->total_entries_arg} = $c->req->search_total_entries + 0; } - $c->stash->{response} = $output; + $c->stash->{$self->stash_key} = $output; } catch { @@ -487,7 +487,7 @@ sub item } else { - $c->stash->{response}->{$self->item_root} = $self->each_object_inflate($c, $c->req->get_object(0)->[0]); + $c->stash->{$self->stash_key}->{$self->item_root} = $self->each_object_inflate($c, $c->req->get_object(0)->[0]); } } @@ -858,25 +858,25 @@ sub end :Private # Check for errors caught elsewhere if ( $c->res->status and $c->res->status != 200 ) { $default_status = $c->res->status; - $c->stash->{response}->{success} = $self->use_json_boolean ? JSON::Any::false : 'false'; + $c->stash->{$self->stash_key}->{success} = $self->use_json_boolean ? JSON::Any::false : 'false'; } elsif ($self->get_errors($c)) { - $c->stash->{response}->{messages} = $self->get_errors($c); - $c->stash->{response}->{success} = $self->use_json_boolean ? JSON::Any::false : 'false'; + $c->stash->{$self->stash_key}->{messages} = $self->get_errors($c); + $c->stash->{$self->stash_key}->{success} = $self->use_json_boolean ? JSON::Any::false : 'false'; $default_status = 400; } else { - $c->stash->{response}->{success} = $self->use_json_boolean ? JSON::Any::true : 'true'; + $c->stash->{$self->stash_key}->{success} = $self->use_json_boolean ? JSON::Any::true : 'true'; $default_status = 200; } unless ($default_status == 200) { - delete $c->stash->{response}->{$self->data_root}; + delete $c->stash->{$self->stash_key}->{$self->data_root}; } elsif($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->{response}->{$self->data_root} = scalar(@$returned_objects) > 1 ? $returned_objects : $returned_objects->[0]; + $c->stash->{$self->stash_key}->{$self->data_root} = scalar(@$returned_objects) > 1 ? $returned_objects : $returned_objects->[0]; } $c->res->status( $default_status || 200 ); @@ -986,9 +986,13 @@ Whatever you would pass to $c->model to get a resultset for this class. MyAppDB: Desired resultset class after accessing your model. MyAppDB::ResultSet::Track for example. By default, it's DBIx::Class::ResultClass::HashRefInflator. Set to empty string to leave resultset class without change. +=head3 stash_key + +Controls where in stash request_data should be stored, and defaults to 'response'. + =head3 data_root -By default, the response data is serialized into $c->stash->{response}->{$self->data_root} and data_root defaults to 'list' to preserve backwards compatibility. This is now configuable to meet the needs of the consuming client. +By default, the response data is serialized into $c->stash->{$self->stash_key}->{$self->data_root} and data_root defaults to 'list' to preserve backwards compatibility. This is now configuable to meet the needs of the consuming client. =head3 use_json_boolean @@ -1101,8 +1105,8 @@ For example if you wanted create to return the JSON for the newly created object $self->next::method($c); if ($c->req->has_objects) { - # $c->stash->{response} will be serialized in the end action - $c->stash->{response}->{$self->data_root} = [ map { { $_->get_inflated_columns } } ($c->req->all_objects) ] ; + # $c->stash->{$self->stash_key} will be serialized in the end action + $c->stash->{$self->stash_key}->{$self->data_root} = [ map { { $_->get_inflated_columns } } ($c->req->all_objects) ] ; } } diff --git a/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm b/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm index 71e8730..280e92a 100644 --- a/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm +++ b/lib/Catalyst/Controller/DBIC/API/StaticArguments.pm @@ -122,6 +122,14 @@ prefetch_arg controls how to reference 'prefetch' in the the request_data has 'prefetch_arg' => ( is => 'ro', isa => Str, default => 'list_prefetch' ); +=attribute_public stash_key is: ro, isa: Str, default: 'response' + +stash_key controls where in stash request_data should be stored + +=cut + +has 'stash_key' => ( is => 'ro', isa => Str, default => 'response'); + =attribute_public data_root is: ro, isa: Str, default: 'list' data_root controls how to reference where the data is in the the request_data -- 1.7.2.3
Subject: 0001-Added-possibility-to-tweak-resultset-class-after-sea.patch
From b383bfd5f73193974031aecf5d3517b6ea104e0b Mon Sep 17 00:00:00 2001 From: Oleg Kostyuk <cub.uanic@gmail.com> Date: Tue, 7 Dec 2010 01:08:59 +0200 Subject: [PATCH] Added possibility to tweak resultset class after searching --- lib/Catalyst/Controller/DBIC/API.pm | 9 +++++++-- .../Controller/DBIC/API/StoredResultSource.pm | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/Catalyst/Controller/DBIC/API.pm b/lib/Catalyst/Controller/DBIC/API.pm index bfd5024..2753a74 100644 --- a/lib/Catalyst/Controller/DBIC/API.pm +++ b/lib/Catalyst/Controller/DBIC/API.pm @@ -30,6 +30,7 @@ __PACKAGE__->config(); __PACKAGE__->config ( action => { setup => { PathPart => 'artist', Chained => '/api/rpc/rpc_base' } }, # define parent chain action and partpath class => 'MyAppDB::Artist', + result_class => 'MyAppDB::ResultSet::Artist', create_requires => ['name', 'age'], create_allows => ['nickname'], update_allows => ['name', 'age', 'nickname'], @@ -331,7 +332,7 @@ sub object_lookup list's steps are broken up into three distinct methods: L</list_munge_parameters>, L</list_perform_search>, and L</list_format_output>. -The goal of this method is to call ->search() on the current_result_set, HashRefInflator the result, and return it in $c->stash->{response}->{$self->data_root}. Please see the individual methods for more details on what actual processing takes place. +The goal of this method is to call ->search() on the current_result_set, change resultset class of the result (if needed), and return it in $c->stash->{response}->{$self->data_root}. Please see the individual methods for more details on what actual processing takes place. If the L</select> config param is defined then the hashes will contain only those columns, otherwise all columns in the object will be returned. L</select> of course supports the function/procedure calling semantics that L<DBIx::Class::ResultSet/select>. In order to have proper column names in the result, provide arguments in L</as> (which also follows L<DBIx::Class::ResultSet/as> semantics. Similarly L</count>, L</page>, L</grouped_by> and L</ordered_by> affect the maximum number of rows returned as well as the ordering and grouping. Note that if select, count, ordered_by or grouped_by request parameters are present then these will override the values set on the class with select becoming bound by the select_exposes attribute. @@ -426,7 +427,7 @@ sub list_format_output my ($self, $c) = @_; my $rs = $c->req->current_result_set->search; - $rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); + $rs->result_class($self->result_class) if $self->result_class; try { @@ -981,6 +982,10 @@ Below are explanations for various configuration parameters. Please see L<Cataly Whatever you would pass to $c->model to get a resultset for this class. MyAppDB::Track for example. +=head3 resultset_class + +Desired resultset class after accessing your model. MyAppDB::ResultSet::Track for example. By default, it's DBIx::Class::ResultClass::HashRefInflator. Set to empty string to leave resultset class without change. + =head3 data_root By default, the response data is serialized into $c->stash->{response}->{$self->data_root} and data_root defaults to 'list' to preserve backwards compatibility. This is now configuable to meet the needs of the consuming client. diff --git a/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm b/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm index dc8859b..5d81b39 100644 --- a/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm +++ b/lib/Catalyst/Controller/DBIC/API/StoredResultSource.pm @@ -17,6 +17,14 @@ class is the name of the class that is the model for this controller has 'class' => ( is => 'ro', isa => Str, writer => '_set_class' ); +=attribute_public result_class is: ro, isa: Str + +result_class is the name of the resultset class that is the model for this controller + +=cut + +has 'result_class' => ( is => 'ro', isa => Str, default => 'DBIx::Class::ResultClass::HashRefInflator' ); + =attribute_public stored_result_source is: ro, isa: L<Catalyst::Controller::DBIC::API::Types/ResultSource> This is the result source for the controller -- 1.7.2.3
About the 'stash_key' patch: This is a leftover from the 1.x versions before nperez rewrote DBIC::API. Do you think it really makes sense to make this configurable? About the other one, I quite like it! nperez and I where discussing how to make the output formatting more flexible for weeks but didn't come up with a really great solution. The main problems was how to stringify inflated objects like DateTime columns. If you have an example for a custom result class which can be used for that I'll gladly add it to the docs.
About the 'stash_key' patch: Show quoted text
> Do you think it really makes sense to make this configurable?
Why not? I want to use C:C:DBIC::API instead of C:C:REST, and part of serialization will be done via existing view, with existing templates. I don't see why change of all templates could be better that this simple patch :) About 'tweak resultset class' patch: Show quoted text
> If you have an example for a custom result class which > can be used for that I'll gladly add it to the docs.
Sorry, I don't have example. I just used: ...... 'result_class' => '', ...... and so I was able to leave result set class as is, and call row methods. And in general about docs: English is not native for me, so I'm not best source of docs :)
Are you on irc? I'd prefer to discuss this in #catalyst as others might have an opinion or other helpful input on this too. DBIC::API uses Catalyst::Action::Serialize internally so it's the same controller option and DBIC::API doesn't need to create the attribute. A doc patch linking to Catalyst::Action::Serialize plus your changes should be fine.
Sorry, but seems I will not have free time on this and next week, at least. Feel free to not wait for me and decide the best route on your own. Thanks!
forgot to close the RT after releasing 2.002004.