@@ -26,14 +26,6 @@ has type => (
26
26
default => sub { shift -> action_namespace },
27
27
);
28
28
29
- has relationships => (
30
- is => ' ro' ,
31
- isa => HashRef,
32
- default => sub { {} },
33
- traits => [' Hash' ],
34
- handles => { has_relationships => ' count' },
35
- );
36
-
37
29
my $MAX_SIZE = 5000;
38
30
39
31
# apply "filters" like \&model but for fabricated data
@@ -128,90 +120,6 @@ sub search : Path('_search') : ActionClass('~Deserialize') {
128
120
} or do { $self -> internal_error( $c , $@ ) };
129
121
}
130
122
131
- sub join : ActionClass(' ~Deserialize' ) {
132
- my ( $self , $c ) = @_ ;
133
- my $joins = $self -> relationships;
134
- my @req_joins = $c -> req-> param(' join' );
135
- my $is_get = ref $c -> stash-> {hits } ? 0 : 1;
136
- my $query
137
- = $c -> req-> params-> {q }
138
- ? { query => { query_string => { query => $c -> req-> params-> {q } } } }
139
- : $c -> req-> data ? $c -> req-> data
140
- : { query => { match_all => {} } };
141
- $c -> detach(
142
- ' /not_allowed' ,
143
- [
144
- ' unknown join type, valid values are '
145
- . Moose::Util::english_list( keys %$joins )
146
- ]
147
- ) if ( scalar grep { !$joins -> {$_ } } @req_joins );
148
-
149
- while ( my ( $join , $config ) = each %$joins ) {
150
- my $has_many = ref $config -> {type };
151
- my ($type ) = $has_many ? @{ $config -> {type } } : $config -> {type };
152
- my $cself = $config -> {self } || $join ;
153
- next unless ( grep { $_ eq $join } @req_joins );
154
- my $data
155
- = $is_get
156
- ? [ $c -> stash ]
157
- : [
158
- map {
159
- $_ -> {_source }
160
- || single_valued_arrayref_to_scalar( $_ -> {fields } )
161
- } @{ $c -> stash-> {hits }-> {hits } }
162
- ];
163
- my @ids = List::AllUtils::uniq grep {defined }
164
- map { ref $cself eq ' CODE' ? $cself -> ($_ ) : $_ -> {$cself } } @$data ;
165
- my $filter = { terms => { $config -> {foreign } => [@ids ] } };
166
- my $filtered = {%$query }; # don't work on $query
167
- $filtered -> {filter }
168
- = $query -> {filter }
169
- ? { and => [ $filter , $query -> {filter } ] }
170
- : $filter ;
171
- my $foreign = eval {
172
- $c -> model(" CPAN::$type " )-> query( $filtered -> {query } )
173
- -> filter( $filtered -> {filter } )-> size(1000)-> raw-> all;
174
- } or do { $self -> internal_error( $c , $@ ) };
175
- $c -> detach(
176
- " /not_allowed" ,
177
- [
178
- ' The number of joined documents exceeded the allowed number of 1000 documents by '
179
- . ( $foreign -> {hits }-> {total } - 1000 )
180
- . ' . Please reduce the number of documents or apply additional filters.'
181
- ]
182
- ) if ( $foreign -> {hits }-> {total } > 1000 );
183
- $c -> stash-> {took } += $foreign -> {took } unless ($is_get );
184
-
185
- if ($has_many ) {
186
- my $many ;
187
- for ( @{ $foreign -> {hits }-> {hits } } ) {
188
- my $list = $many -> { $_ -> {_source }-> { $config -> {foreign } } }
189
- ||= [];
190
- push ( @$list , $_ );
191
- }
192
- $foreign = $many ;
193
- }
194
- else {
195
- $foreign = { map { $_ -> {_source }-> { $config -> {foreign } } => $_ }
196
- @{ $foreign -> {hits }-> {hits } } };
197
- }
198
- for (@$data ) {
199
- my $key = ref $cself eq ' CODE' ? $cself -> ($_ ) : $_ -> {$cself };
200
- next unless ($key );
201
- my $result = $foreign -> {$key };
202
- $_ -> {$join }
203
- = $has_many
204
- ? {
205
- hits => {
206
- hits => $result ,
207
- total => scalar @{ $result || [] }
208
- }
209
- }
210
- : $result ;
211
- }
212
- }
213
- }
214
-
215
123
sub not_found : Private {
216
124
my ( $self , $c ) = @_ ;
217
125
$c -> cdn_never_cache(1);
@@ -238,57 +146,8 @@ sub internal_error {
238
146
239
147
sub end : Private {
240
148
my ( $self , $c ) = @_ ;
241
- $c -> forward(' join' )
242
- if ( $self -> has_relationships && $c -> req-> param(' join' ) );
243
149
$c -> forward(' /end' );
244
150
}
245
151
246
152
__PACKAGE__ -> meta-> make_immutable;
247
153
1;
248
-
249
- __END__
250
-
251
- =head1 ATTRIBUTES
252
-
253
- =head2 relationships
254
-
255
- MetaCPAN::Server::Controller::Author->config(
256
- relationships => {
257
- release => {
258
- type => ['Release'],
259
- self => 'pauseid',
260
- foreign => 'author',
261
- }
262
- }
263
- );
264
-
265
- Contains a HashRef of relationships with other controllers.
266
- If C<type > is an ArrayRef, the relationship is considered a
267
- I<has many > relationship.
268
-
269
- Unless a C<self > exists, the name of the relationship is used
270
- as key to join on. C<self > can also be a CodeRef, if the foreign
271
- key is build from several local keys. In this case, again the name of
272
- the relationship is used as key in the result.
273
-
274
- C<foreign > refers to the foreign key on the C<type > controller the data
275
- is joined with.
276
-
277
- =head1 ACTIONS
278
-
279
- =head2 join
280
-
281
- This action is called if the controller has L</relationships> defined
282
- and if one or more C<join > query parameters are defined. It then
283
- does a I<left join > based on the information provided by
284
- L</relationships> .
285
-
286
- This works both for GET requests, where only one document is requested
287
- and search requests, where a number of documents is returned.
288
- It also passes through search data (either the C<q > query string or
289
- the request body).
290
-
291
- B<The number of documents that can be joined is limited to 1000 per
292
- relationship for now.>
293
-
294
- =cut
0 commit comments