line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Catalyst::Helper::Controller::DBIC::API::REST; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
5728
|
use Class::Load; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
56
|
|
4
|
1
|
|
|
1
|
|
4
|
use namespace::autoclean; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
10
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
67
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
18
|
|
7
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
22
|
|
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
3
|
use FindBin; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
33
|
|
10
|
1
|
|
|
1
|
|
4
|
use File::Spec; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
23
|
|
11
|
1
|
|
|
1
|
|
786
|
use Path::Tiny; |
|
1
|
|
|
|
|
8839
|
|
|
1
|
|
|
|
|
57
|
|
12
|
1
|
|
|
1
|
|
7
|
use List::Util; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
61
|
|
13
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
4
|
use lib "$FindBin::Bin/../lib"; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
BEGIN { |
17
|
|
|
|
|
|
|
|
18
|
1
|
|
|
1
|
|
830
|
our $VERSION = '0.09'; # VERSION |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 NAME |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Catalyst::Helper::Controller::DBIC::API::REST |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=encoding UTF-8 |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 SYNOPSIS |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
$ catalyst.pl MyApp |
30
|
|
|
|
|
|
|
$ cd MyApp |
31
|
|
|
|
|
|
|
$ script/myapp_create.pl controller API::REST DBIC::API::REST \ |
32
|
|
|
|
|
|
|
MyApp::Schema MyApp::Model::DB |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
... |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
package MyApp::Controller::API::REST::Producer; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use strict; |
40
|
|
|
|
|
|
|
use warnings; |
41
|
|
|
|
|
|
|
use base qw/MyApp::ControllerBase::REST/; |
42
|
|
|
|
|
|
|
use JSON::XS; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
__PACKAGE__->config( |
45
|
|
|
|
|
|
|
action => { setup => { |
46
|
|
|
|
|
|
|
PathPart => 'producer', |
47
|
|
|
|
|
|
|
Chained => '/api/rest/rest_base' } |
48
|
|
|
|
|
|
|
}, # define parent chain action and partpath |
49
|
|
|
|
|
|
|
class => 'DB::Producer', # DBIC result class |
50
|
|
|
|
|
|
|
create_requires => [qw/name/], # columns required |
51
|
|
|
|
|
|
|
# to create |
52
|
|
|
|
|
|
|
create_allows => [qw//], # additional non-required |
53
|
|
|
|
|
|
|
# columns that |
54
|
|
|
|
|
|
|
# create allows |
55
|
|
|
|
|
|
|
update_allows => [qw/name/], # columns that |
56
|
|
|
|
|
|
|
# update allows |
57
|
|
|
|
|
|
|
list_returns => [qw/producerid name/], # columns that |
58
|
|
|
|
|
|
|
# list returns |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
list_prefetch_allows => [ # every possible prefetch param allowed |
61
|
|
|
|
|
|
|
[qw/cd_to_producer/], { 'cd_to_producer' => [qw//] }, |
62
|
|
|
|
|
|
|
[qw/tags/], { 'tags' => [qw//] }, |
63
|
|
|
|
|
|
|
[qw/tracks/], { 'tracks' => [qw//] }, |
64
|
|
|
|
|
|
|
], |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
list_ordered_by => [ qw/producerid/ ], |
67
|
|
|
|
|
|
|
# order of generated list |
68
|
|
|
|
|
|
|
list_search_exposes => [ qw/producerid name/ ], |
69
|
|
|
|
|
|
|
# columns that can be searched on via list |
70
|
|
|
|
|
|
|
); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head1 DESCRIPTION |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
This creates REST controllers according to the specifications at |
75
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API> and L<Catalyst::Controller::DBIC::API::REST> |
76
|
|
|
|
|
|
|
for all the classes in your Catalyst app. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
It creates the following files: |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
MyApp/lib/MyApp/Controller/API.pm |
81
|
|
|
|
|
|
|
MyApp/lib/MyApp/Controller/API/REST.pm |
82
|
|
|
|
|
|
|
MyApp/lib/MyApp/Controller/API/REST/* |
83
|
|
|
|
|
|
|
MyApp/lib/MyApp/ControllerBase/REST.pm |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
Individual class controllers are under MyApp/lib/MyApp/Controller/API/REST/*. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=head2 CONFIGURATION |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
The idea is to make configuration as painless and as automatic as possible, so most |
90
|
|
|
|
|
|
|
of the work has been done for you. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
There are 8 __PACKAGE__->config(...) options for L<Catalyst::Controller::DBIC::API/CONFIGURATION>. |
93
|
|
|
|
|
|
|
Here are the defaults. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head2 create_requires |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
All non-nullable columns that are (1) not autoincrementing, |
98
|
|
|
|
|
|
|
(2) don't have a default value, are neither (3) nextvals, |
99
|
|
|
|
|
|
|
(4) sequences, nor (5) timestamps. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head2 create_allows |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
All nullable columns that are (1) not autoincrementing, |
104
|
|
|
|
|
|
|
(2) don't have a default value, are neither (3) nextvals, |
105
|
|
|
|
|
|
|
(4) sequences, nor (5) timestamps. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=head2 update_allows |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
The union of create_requires and create_allows. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head2 list_returns |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Every column in the class. |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head2 list_prefetch |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Nothing is prefetched by default. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=head2 list_prefetch_allows |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
(1) An arrayref consisting of the name of each of the class's |
122
|
|
|
|
|
|
|
has_many relationships, accompanied by (2) a hashref keyed on |
123
|
|
|
|
|
|
|
the name of that relationship, whose values are the names of |
124
|
|
|
|
|
|
|
its has_many's, e.g., in the "Producer" controller above, a |
125
|
|
|
|
|
|
|
Producer has many cd_to_producers, many tags, and many tracks. |
126
|
|
|
|
|
|
|
None of those classes have any has_many's: |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
list_prefetch_allows => [ |
129
|
|
|
|
|
|
|
[qw/cd_to_producer/], { 'cd_to_producer' => [qw//] }, |
130
|
|
|
|
|
|
|
[qw/tags/], { 'tags' => [qw//] }, |
131
|
|
|
|
|
|
|
[qw/tracks/], { 'tracks' => [qw//] }, |
132
|
|
|
|
|
|
|
], |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head2 list_ordered_by |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
The primary key. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 list_search_exposes |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
(1) An arrayref consisting of the name of each column in the class, |
141
|
|
|
|
|
|
|
and (2) a hashref keyed on the name of each of the class's has many |
142
|
|
|
|
|
|
|
relationships, the values of which are all the columns in the |
143
|
|
|
|
|
|
|
corresponding class, e.g., |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
list_search_exposes => [ |
146
|
|
|
|
|
|
|
qw/cdid artist title year/, |
147
|
|
|
|
|
|
|
{ 'cd_to_producer' => [qw/cd producer/] }, |
148
|
|
|
|
|
|
|
{ 'tags' => [qw/tagid cd tag/] }, |
149
|
|
|
|
|
|
|
{ 'tracks' => [qw/trackid cd position title last_updated_on/] }, |
150
|
|
|
|
|
|
|
], # columns that can be searched on via list |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head1 CONTROLLERBASE |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
Following the advice in L<Catalyst::Controller::DBIC::API/EXTENDING>, this |
155
|
|
|
|
|
|
|
module creates an intermediate class between your controllers and |
156
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API::REST>. It contains one method, create, |
157
|
|
|
|
|
|
|
which serializes object information and stores it in the stash, which is |
158
|
|
|
|
|
|
|
not the default behavior. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head1 METHODS |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 mk_compclass |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
This is the meat of the helper. It writes the directory structure if it is |
165
|
|
|
|
|
|
|
not in place, API.pm, REST.pm, the controllerbase, and the result class |
166
|
|
|
|
|
|
|
controllers. It replaces $helper->{} values as it goes through, rendering |
167
|
|
|
|
|
|
|
the files for each. |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=over |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=back |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=head1 AUTHOR |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Amiri Barksdale E<lt>amiri@roosterpirates.comE<gt> |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Franck Cuny (lumberjaph) <franck@lumberjaph.net> |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
Pablo RodrÃguez González <pablo.rodriguez.gonzalez@gmail.com> |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Chris Weyl (RsrchBoy) <cweyl@alumni.drew.edu> |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=head1 SEE ALSO |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API> |
188
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API::REST> |
189
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API::RPC> |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head1 LICENSE |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
194
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=cut |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub mk_compclass { |
199
|
1
|
|
|
1
|
1
|
14
|
my ( $self, $helper, $schema_class, $model, @extra_options ) = @_; |
200
|
1
|
|
|
|
|
2
|
my %extra_options = map {split /=/} @extra_options; |
|
0
|
|
|
|
|
0
|
|
201
|
|
|
|
|
|
|
|
202
|
1
|
|
33
|
|
|
8
|
$schema_class ||= $helper->{app} . '::Schema'; |
203
|
1
|
|
33
|
|
|
5
|
$model ||= $helper->{app} . '::Model::DB'; |
204
|
|
|
|
|
|
|
|
205
|
1
|
|
|
|
|
6
|
( my $model_base = $model ) =~ s/^.*::Model:://; |
206
|
|
|
|
|
|
|
|
207
|
1
|
50
|
|
|
|
5
|
$helper->{script} = File::Spec->catdir( $helper->{dir}, 'script' ) if $helper->{dir}; |
208
|
1
|
|
|
|
|
6
|
$helper->{appprefix} = Catalyst::Utils::appprefix( $helper->{name} ); |
209
|
1
|
|
|
|
|
12
|
my @path_to_name = split( /::/, $helper->{name} ); |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
## Connect to schema for class info |
212
|
1
|
|
|
|
|
4
|
Class::Load::load_class($schema_class); |
213
|
1
|
|
|
|
|
135755
|
my $schema = $schema_class->connect; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
my $path_app = File::Spec->catdir( $FindBin::Bin, "..", "lib", |
216
|
1
|
|
|
|
|
63977
|
split( /::/, $helper->{app} ) ); |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
## Make api base |
219
|
|
|
|
|
|
|
my $api_file |
220
|
1
|
|
|
|
|
15
|
= File::Spec->catfile( $path_app, $helper->{type}, "API.pm" ); |
221
|
|
|
|
|
|
|
|
222
|
1
|
|
|
|
|
17
|
( my $api_path = $api_file ) =~ s/\.pm$//; |
223
|
1
|
|
|
|
|
7
|
$helper->mk_dir($api_path); |
224
|
1
|
|
|
|
|
329
|
$helper->render_file( 'apibase', $api_file ); |
225
|
1
|
|
|
|
|
45310
|
$helper->{test} = $helper->next_test('API'); |
226
|
1
|
|
|
|
|
324
|
$helper->_mk_comptest; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
## Make rest base |
229
|
|
|
|
|
|
|
my $rest_file |
230
|
1
|
|
|
|
|
5822
|
= File::Spec->catfile( $path_app, $helper->{type}, "API", "REST.pm" ); |
231
|
|
|
|
|
|
|
|
232
|
1
|
|
|
|
|
8
|
( my $rest_path = $rest_file ) =~ s/\.pm$//; |
233
|
1
|
|
|
|
|
5
|
$helper->mk_dir($rest_path); |
234
|
1
|
|
|
|
|
323
|
$helper->render_file( 'restbase', $rest_file ); |
235
|
1
|
|
|
|
|
1843
|
$helper->{test} = $helper->next_test('API_REST'); |
236
|
1
|
|
|
|
|
336
|
$helper->_mk_comptest; |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
## Make controller base |
239
|
1
|
|
|
|
|
5487
|
my $base_file |
240
|
|
|
|
|
|
|
= File::Spec->catfile( $path_app, "ControllerBase", "REST.pm" ); |
241
|
|
|
|
|
|
|
|
242
|
1
|
|
|
|
|
9
|
$helper->mk_dir( File::Spec->catdir( $path_app, "ControllerBase" ) ); |
243
|
1
|
|
|
|
|
285
|
$helper->render_file( 'controllerbase', $base_file ); |
244
|
1
|
|
|
|
|
1780
|
$helper->{test} = $helper->next_test('controller_base'); |
245
|
1
|
|
|
|
|
267
|
$helper->_mk_comptest; |
246
|
|
|
|
|
|
|
|
247
|
1
|
|
|
|
|
5598
|
$helper->mk_dir( File::Spec->catdir( $path_app, $helper->{type}, @path_to_name )); |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
## Make result class controllers |
250
|
1
|
|
|
|
|
150
|
for my $source ( $schema->sources ) { |
251
|
6
|
|
|
|
|
28863
|
my ( $class, $result_class ); |
252
|
|
|
|
|
|
|
my $file |
253
|
6
|
|
|
|
|
86
|
= File::Spec->catfile( $path_app, $helper->{type}, @path_to_name, |
254
|
|
|
|
|
|
|
split(/::/, $source . ".pm") ); |
255
|
6
|
|
|
|
|
28
|
Path::Tiny::path($file)->parent()->mkpath; |
256
|
|
|
|
|
|
|
$class |
257
|
|
|
|
|
|
|
= $helper->{app} . "::" |
258
|
|
|
|
|
|
|
. $helper->{type} |
259
|
6
|
|
|
|
|
916
|
. "::" . join("::", @path_to_name) ."::" |
260
|
|
|
|
|
|
|
. $source; |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
#$result_class = $helper->{app} . "::Model::DB::" . $source; |
263
|
6
|
|
|
|
|
13
|
$result_class = $model_base . '::' . $source; |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
### Declare config vars |
266
|
6
|
|
|
|
|
10
|
my @create_requires; |
267
|
|
|
|
|
|
|
my @create_allows; |
268
|
0
|
|
|
|
|
0
|
my @update_allows; |
269
|
0
|
|
|
|
|
0
|
my @list_prefetch; |
270
|
6
|
|
|
|
|
34
|
my @list_search_exposes = my @list_returns |
271
|
|
|
|
|
|
|
= $schema->source($source)->columns; |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
### HAIRY RELATIONSHIPS STUFF |
274
|
6
|
|
|
|
|
387
|
my @sub_list_search_exposes = my @list_prefetch_allows |
275
|
|
|
|
|
|
|
= _return_has_many_list( |
276
|
|
|
|
|
|
|
$schema->source($source)->_relationships ); |
277
|
|
|
|
|
|
|
@list_prefetch_allows = map { |
278
|
6
|
|
|
|
|
13
|
my $ref = $_; |
|
4
|
|
|
|
|
6
|
|
279
|
|
|
|
|
|
|
qq|[qw/$ref->[0]/], { | |
280
|
|
|
|
|
|
|
. qq| '$ref->[0]' => [qw/| |
281
|
|
|
|
|
|
|
. join( |
282
|
|
|
|
|
|
|
' ', |
283
|
4
|
|
|
|
|
32
|
map { $_->[0] } _return_has_many_list( |
|
3
|
|
|
|
|
10
|
|
284
|
|
|
|
|
|
|
$schema->source( $ref->[1] )->_relationships |
285
|
|
|
|
|
|
|
) |
286
|
|
|
|
|
|
|
) . qq|/] },\n\t\t|; |
287
|
|
|
|
|
|
|
} @list_prefetch_allows; |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
@sub_list_search_exposes = map { |
290
|
6
|
|
|
|
|
12
|
my $ref = $_; |
|
4
|
|
|
|
|
121
|
|
291
|
4
|
|
|
|
|
12
|
qq|{ '$ref->[0]' => [qw/| |
292
|
|
|
|
|
|
|
. join( ' ', $schema->source( $ref->[1] )->columns ) |
293
|
|
|
|
|
|
|
. qq|/] },\n\t\t|; |
294
|
|
|
|
|
|
|
} @sub_list_search_exposes; |
295
|
|
|
|
|
|
|
### END HAIRY RELATIONSHIP STUFF |
296
|
|
|
|
|
|
|
|
297
|
6
|
|
|
|
|
135
|
my @list_ordered_by = $schema->source($source)->primary_columns; |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
### Prepare hash of column info for this class, so we can extract config |
300
|
|
|
|
|
|
|
my %source_col_info |
301
|
6
|
|
|
|
|
230
|
= map { $_, $schema->source($source)->column_info($_) } |
|
18
|
|
|
|
|
643
|
|
302
|
|
|
|
|
|
|
$schema->source($source)->columns; |
303
|
6
|
|
|
|
|
237
|
for my $k ( sort keys %source_col_info ) { |
304
|
1
|
|
|
1
|
|
6
|
no warnings qw/uninitialized/; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
591
|
|
305
|
18
|
100
|
66
|
|
|
104
|
if (( !$source_col_info{$k}->{'is_auto_increment'} ) |
306
|
|
|
|
|
|
|
&& !( |
307
|
|
|
|
|
|
|
$source_col_info{$k}->{'default_value'} |
308
|
|
|
|
|
|
|
=~ /(nextval|sequence|timestamp)/ |
309
|
|
|
|
|
|
|
) |
310
|
|
|
|
|
|
|
) |
311
|
|
|
|
|
|
|
{ |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
### Extract create required |
314
|
|
|
|
|
|
|
push @create_requires, $k |
315
|
13
|
100
|
|
|
|
27
|
if !$source_col_info{$k}->{'is_nullable'}; |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
### Extract create_allowed |
318
|
|
|
|
|
|
|
push @create_allows, $k |
319
|
13
|
100
|
|
|
|
30
|
if $source_col_info{$k}->{'is_nullable'}; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
else { } |
322
|
18
|
|
|
|
|
31
|
@update_allows = ( @create_requires, @create_allows ); |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
6
|
|
|
|
|
14
|
$helper->{package} = $class; |
326
|
6
|
|
|
|
|
17
|
$helper->{class} = $model_base . '::' . $source; |
327
|
6
|
50
|
|
|
|
16
|
if (defined $extra_options{'result_class'}) { |
328
|
0
|
|
|
|
|
0
|
$helper->{result_class} = $extra_options{'result_class'}; |
329
|
|
|
|
|
|
|
} |
330
|
6
|
|
|
|
|
148
|
$helper->{path_class_name} = join("/", (map {lc} @path_to_name[ 2 .. (scalar @path_to_name - 1)]), split(/::|\./, $schema->source_registrations->{$source}->name)); |
|
0
|
|
|
|
|
0
|
|
331
|
|
|
|
|
|
|
$helper->{class_name} |
332
|
6
|
|
|
6
|
|
224
|
= List::Util::first {1;} reverse split(/::/, $schema->source_registrations->{$source}->name); |
|
6
|
|
|
|
|
87
|
|
333
|
6
|
|
|
|
|
20
|
$helper->{file} = $file; |
334
|
6
|
|
|
|
|
17
|
$helper->{create_requires} = join( ' ', @create_requires ); |
335
|
6
|
|
|
|
|
12
|
$helper->{create_allows} = join( ' ', @create_allows ); |
336
|
6
|
|
|
|
|
15
|
$helper->{list_returns} = join( ' ', @list_returns ); |
337
|
6
|
|
|
|
|
13
|
$helper->{list_search_exposes} = join( ' ', @list_search_exposes ); |
338
|
|
|
|
|
|
|
$helper->{sub_list_search_exposes} |
339
|
6
|
|
|
|
|
11
|
= join( '', @sub_list_search_exposes ); |
340
|
6
|
|
|
|
|
12
|
$helper->{update_allows} = join( ' ', @update_allows ); |
341
|
6
|
100
|
|
|
|
20
|
$helper->{list_prefetch_allows} = join( '', @list_prefetch_allows ) |
342
|
|
|
|
|
|
|
if scalar @list_prefetch_allows > 0; |
343
|
|
|
|
|
|
|
$helper->{list_prefetch} |
344
|
6
|
50
|
|
|
|
13
|
= join( ', ', map {qq|'$_->[0]'|} @list_prefetch ) |
|
0
|
|
|
|
|
0
|
|
345
|
|
|
|
|
|
|
if scalar @list_prefetch > 0; |
346
|
6
|
|
|
|
|
16
|
$helper->{list_ordered_by} = join( ' ', @list_ordered_by ); |
347
|
6
|
|
|
|
|
19
|
$helper->render_file( 'compclass', $file ); |
348
|
6
|
|
|
|
|
56375
|
$helper->{test} = $helper->next_test($source); |
349
|
6
|
|
|
|
|
1844
|
$helper->_mk_comptest; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
sub _return_has_many_list { |
354
|
10
|
|
|
10
|
|
448
|
my ($relationships) = @_; |
355
|
|
|
|
|
|
|
return |
356
|
17
|
|
|
|
|
76
|
grep { $relationships->{ $_->[0] }->{attrs}->{accessor} =~ /multi/ } |
357
|
10
|
|
|
|
|
47
|
map { [ $_, $relationships->{$_}->{source} ] } |
|
17
|
|
|
|
|
51
|
|
358
|
|
|
|
|
|
|
sort keys %$relationships; |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
1; |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
__DATA__ |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=begin pod_to_ignore |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
__apibase__ |
368
|
|
|
|
|
|
|
package [% app %]::Controller::API; |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
use strict; |
371
|
|
|
|
|
|
|
use warnings; |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
use parent qw/Catalyst::Controller/; |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
sub api_base : Chained('/') PathPart('api') CaptureArgs(0) { |
376
|
|
|
|
|
|
|
my ( $self, $c ) = @_; |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
1; |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
__restbase__ |
382
|
|
|
|
|
|
|
package [% app %]::Controller::API::REST; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
use strict; |
385
|
|
|
|
|
|
|
use warnings; |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
use parent qw/Catalyst::Controller/; |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub rest_base : Chained('/api/api_base') PathPart('rest') CaptureArgs(0) { |
390
|
|
|
|
|
|
|
my ($self, $c) = @_; |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
1; |
394
|
|
|
|
|
|
|
__controllerbase__ |
395
|
|
|
|
|
|
|
package [% app %]::ControllerBase::REST; |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
use strict; |
398
|
|
|
|
|
|
|
use warnings; |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
use parent qw/Catalyst::Controller::DBIC::API::REST/; |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub create :Private { |
403
|
|
|
|
|
|
|
my ($self, $c) = @_; |
404
|
|
|
|
|
|
|
$self->next::method($c); |
405
|
|
|
|
|
|
|
if ($c->stash->{created_object}) { |
406
|
|
|
|
|
|
|
%{$c->stash->{response}->{new_object}} = $c->stash->{created_object}->get_columns; |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
1; |
411
|
|
|
|
|
|
|
__compclass__ |
412
|
|
|
|
|
|
|
package [% package %]; |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
use strict; |
415
|
|
|
|
|
|
|
use warnings; |
416
|
|
|
|
|
|
|
use JSON::XS; |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
use parent qw/[% app %]::ControllerBase::REST/; |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
__PACKAGE__->config( |
421
|
|
|
|
|
|
|
# Define parent chain action and partpath |
422
|
|
|
|
|
|
|
action => { setup => { PathPart => '[% path_class_name %]', Chained => '/api/rest/rest_base' } }, |
423
|
|
|
|
|
|
|
# DBIC result class |
424
|
|
|
|
|
|
|
class => '[% class %]', |
425
|
|
|
|
|
|
|
[% IF result_class %] |
426
|
|
|
|
|
|
|
result_class => '[% result_class %]', |
427
|
|
|
|
|
|
|
[% END %] |
428
|
|
|
|
|
|
|
# Columns required to create |
429
|
|
|
|
|
|
|
create_requires => [qw/[% create_requires %]/], |
430
|
|
|
|
|
|
|
# Additional non-required columns that create allows |
431
|
|
|
|
|
|
|
create_allows => [qw/[% create_allows %]/], |
432
|
|
|
|
|
|
|
# Columns that update allows |
433
|
|
|
|
|
|
|
update_allows => [qw/[% update_allows %]/], |
434
|
|
|
|
|
|
|
# Columns that list returns |
435
|
|
|
|
|
|
|
list_returns => [qw/[% list_returns %]/], |
436
|
|
|
|
|
|
|
[% IF list_prefetch %] |
437
|
|
|
|
|
|
|
# relationships prefetched by default |
438
|
|
|
|
|
|
|
list_prefetch => [[% list_prefetch %]], |
439
|
|
|
|
|
|
|
[% END %] |
440
|
|
|
|
|
|
|
[% IF list_prefetch_allows %] |
441
|
|
|
|
|
|
|
# Every possible prefetch param allowed |
442
|
|
|
|
|
|
|
list_prefetch_allows => [ |
443
|
|
|
|
|
|
|
[% list_prefetch_allows %] |
444
|
|
|
|
|
|
|
], |
445
|
|
|
|
|
|
|
[% END %] |
446
|
|
|
|
|
|
|
# Order of generated list |
447
|
|
|
|
|
|
|
list_ordered_by => [qw/[% list_ordered_by %]/], |
448
|
|
|
|
|
|
|
# columns that can be searched on via list |
449
|
|
|
|
|
|
|
list_search_exposes => [ |
450
|
|
|
|
|
|
|
qw/[% list_search_exposes %]/, |
451
|
|
|
|
|
|
|
[% sub_list_search_exposes %] |
452
|
|
|
|
|
|
|
],); |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=head1 NAME |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
[% PACKAGE %] - REST Controller for [% schema_class %] |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=head1 DESCRIPTION |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
REST Methods to access the DBIC Result Class [% class_name %] |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=head1 AUTHOR |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
[% author %] |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=head1 SEE ALSO |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API> |
469
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API::REST> |
470
|
|
|
|
|
|
|
L<Catalyst::Controller::DBIC::API::RPC> |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=head1 LICENSE |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
[% license %] |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=cut |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
1; |