source: server/trunk/web/lib/Sophie/Controller/Search.pm @ 388

Last change on this file since 388 was 351, checked in by nanardon, 13 years ago
  • optimize in a fester way
File size: 8.9 KB
Line 
1package Sophie::Controller::Search;
2use Moose;
3use namespace::autoclean;
4use Sophie;
5
6BEGIN {extends 'Catalyst::Controller'; }
7
8=head1 NAME
9
10Sophie::Controller::Search - Catalyst Controller
11
12=head1 DESCRIPTION
13
14Catalyst Controller.
15
16=head1 METHODS
17
18=cut
19
20
21=head2 index
22
23=cut
24
25sub index :Path :Args(0) {
26    my ($self, $c) = @_;
27
28    if ($c->req->param('page')) {
29        $c->req->params->{search} = $c->session->{search};
30        $c->req->params->{type} = $c->session->{type};
31        $c->req->params->{deptype} = $c->session->{deptype};
32        foreach (qw(distribution release arch)) {
33            $c->req->params->{$_} = $c->session->{search_dist}{$_};
34        }
35    } else {
36        $c->session->{search} = $c->req->params->{search};
37        $c->session->{type} = $c->req->params->{type};
38        $c->session->{deptype} = $c->req->params->{deptype};
39        foreach (qw(distribution release arch)) {
40            $c->session->{search_dist}{$_} = $c->req->params->{$_};
41        }
42    }
43
44    my $searchspec = { %{ $c->session->{search_dist} } };
45
46    for ($c->req->param('type')) {
47        /^fuzzyname$/ and do {
48            $c->stash->{sargs} = [ {}, $c->req->param('search') ];
49            $c->visit('/search/rpm/fuzzy_rpc', [ $searchspec, $c->req->param('search') ||
50                    undef ]);
51            last;
52        };
53        /^byname$/ and do {
54            $c->stash->{sargs} = [ {}, $c->req->param('search') ];
55            $c->visit('/search/rpm/byname_rpc', [ $searchspec, $c->req->param('search') ||
56                    undef ]);
57            last;
58        };
59        /^bydep$/ and do {
60            my @args = ($c->req->param('deptype'), grep { $_ }
61                split(/\s+/, $c->req->param('search') || '' ));
62            $c->stash->{sargs} = [ {}, @args ],
63            $c->visit('/search/rpm/bydep_rpc', [ $searchspec, @args ]);
64            last;
65        };
66        /^byfile$/ and do {
67            my @args = ($c->req->param('search') || '');
68            $c->stash->{sargs} = [ {}, @args ],
69            $c->visit('/search/rpm/byfile_rpc', [ $searchspec, @args ]);
70            last;
71        };
72    }
73    #$c->forward('/search/rpm/end');
74}
75
76sub results :Local {
77    my ( $self, $c ) = @_;
78
79    if ($c->req->param('page')) {
80        $c->req->params->{search} ||= $c->session->{search};
81    }
82
83    if ($c->req->param('search')) {
84        $c->session->{search} = $c->req->param('search');
85        $c->visit('/search/rpm/quick', [
86                {
87                    src => 0,
88                } , grep { $_ } split(/\s/, $c->req->param('search')) ]);
89
90    }
91    $c->forward('/search/rpm/end');
92}
93
94sub adv_search :Local {
95    my ( $self, $c ) = @_;
96}
97
98sub distrib_search : Private {
99    my ( $self, $c, $searchspec, $asfilter ) = @_;
100
101    # if asfilter is set, return undef if nothing would have been filter
102    if (my $rs = $c->forward('/distrib/distrib_rs', [ $searchspec, $asfilter ]))
103    {
104        return $rs
105            ->search_related('MediasPaths')
106            ->search_related('Paths')
107            ->search_related('Rpmfiles');
108        } else {
109            return;
110        }
111}
112
113sub byname_rs : Private {
114    my ( $self, $c, $searchspec, $name, $sense, $evr ) = @_;
115    $searchspec ||= {};
116
117    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
118
119    return $c->model('Base::Rpms')->search(
120        {
121            -and => [ 
122                (exists($searchspec->{src})
123                    ? { issrc => $searchspec->{src} ? 1 : 0 }
124                    : ()),
125                { name => $name },
126                ( $evr
127                    ? { -nest => \[ 
128                        "rpmdepmatch(rpmsenseflag('='), evr, rpmsenseflag(?), ?)",
129                        [ plain_text => $sense],
130                        [ plain_text => $evr ],
131                    ] }
132                    : ()),
133                ($distrs
134                    ? { pkgid => { IN => $distrs->get_column('pkgid')->as_query, }, }
135                    : ()),
136            ]     
137        },
138        {
139                order_by => [ 'name', 'evr using >>', 'issrc' ],
140        }
141    );
142}
143
144sub bytag_rs : Private {
145    my ( $self, $c, $searchspec, $tag, $tagvalue ) = @_;
146    $searchspec ||= {};
147
148    my $tagrs = $c->model('Base')->resultset('Tags')
149        ->search({ tagname => lc($tag), value => $tagvalue})
150        ->get_column('pkgid');
151    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
152    return $c->model('Base')->resultset('Rpms')->search(
153        {
154            -and => [ 
155                (exists($searchspec->{src})
156                    ? { issrc => $searchspec->{src} ? 1 : 0 }
157                    : ()),
158                { pkgid => 
159                    { IN => $tagrs->as_query, },
160                },
161                $distrs
162                    ? { pkgid => { IN => $distrs->get_column('pkgid')->as_query, }, }
163                    : (),
164            ]     
165        },
166    );
167}
168
169sub bypkgid_rs : Private {
170    my ( $self, $c, $searchspec, $pkgid ) = @_;
171    $searchspec ||= {};
172
173    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
174
175    return $c->model('Base::Rpms')->search(
176        {
177            -and => [ 
178                (exists($searchspec->{src})
179                    ? { issrc => $searchspec->{src} ? 1 : 0 }
180                    : ()),
181                { pkgid => $pkgid },
182                $distrs
183                    ? { pkgid => { IN => $distrs->get_column('pkgid')->as_query, } }
184                    : ()
185            ]     
186        },
187    );
188}
189
190sub deps_rs : Private {
191    my ($self, $c, $searchspec, $deptype, $depname, $depsense, $depevr ) = @_;
192
193        my $rs = $c->model('Base::Deps')->search(
194        {
195            -and => [
196            { deptype => $deptype },
197            { depname => $depname },
198            ($depsense
199                ? ({-nest => \[
200                    'rpmdepmatch(flags, me.evr, rpmsenseflag(?), ?)',
201                    [ plain_text => $depsense],
202                    [ plain_text => $depevr ]
203                ]})
204            : ()),
205            ($searchspec->{pkgid}
206                ? { 'pkgid' => $searchspec->{pkgid} }
207                : ()),
208            ]
209        },
210        {
211            '+select' => [ { rpmsenseflag => 'flags' }, 'depname',
212                'me.evr' ],
213            '+as'     => [ qw(sense name evr) ],
214
215        }
216    );
217    if (exists($searchspec->{src})) {
218        $rs = $rs->search_related('Rpms',
219            { issrc => $searchspec->{src} ? 1 : 0 }
220        )
221    }
222    return $c->model('BaseSearch')->apply_rpm_filter($rs, $searchspec);
223}
224
225sub file_rs : Private {
226    my ( $self, $c, $searchspec, $file) = @_;
227    my ($dirname, $basename) = $file =~ m:^(.*/)?([^/]+)$:;
228    $dirname =~ m:^[/]: or $dirname = undef;
229    if (!$dirname) {
230        if ($file =~ /(\*|\?)/) {
231            $file =~ tr/*?/%_/;
232        } else {
233            $file = '%' . $file;
234        }
235    }
236    $searchspec ||= {};
237
238    my $rs = $c->model('Base::Files')->search(
239        {
240            -and => [
241                ($dirname
242                    ? (dirname => $dirname)
243                    : ()),
244                { 'dirname || basename' => { LIKE => $file } },
245                basename => $basename,
246                ($searchspec->{content} ? { has_content => 1 } : ()),
247                ($searchspec->{pkgid}
248                    ? { 'pkgid' => { IN => $searchspec->{pkgid} } }
249                    : ()),
250            ],
251        },
252        {
253            '+select' => [
254                'contents is NOT NULL as has_content',
255                { rpmfilesmode => 'mode' },
256            ],
257            '+as' => [ qw(has_content perm), ]
258        }
259    );
260    if (exists($searchspec->{src})) {
261        $rs = $rs->search_related('Rpms',
262            { issrc => $searchspec->{src} ? 1 : 0 }
263        )
264    }
265    return $c->model('BaseSearch')->apply_rpm_filter($rs, $searchspec);
266}
267
268sub end : Private {
269    my ($self, $c, $searchspec) = @_;
270
271    if ($c->action =~ m:search/[^/]+/.:) {
272        my $rs = $c->stash->{rs}->search(
273            {},
274            {
275                page => $searchspec->{page} || 
276                     $c->req->param('page') || 1,
277                rows => $searchspec->{rows} || 
278                     $c->req->param('rows') || 10,
279            },
280        );
281
282        $c->stash->{rs} = $rs;
283        my @results = map { { $_->get_columns } } $rs->all;
284
285        $c->stash->{xmlrpc} = {};
286        if (!$searchspec->{nopager}) {
287            my $pager = $c->stash->{rs}->pager;
288            $c->stash->{pager} = $pager;
289            $c->stash->{xmlrpc} = {
290                    pages => $pager->last_page,
291                    current_page => $pager->current_page,
292                    total_entries => $pager->total_entries,
293                    entries_per_page => $pager->entries_per_page,
294            };
295        }
296        $c->stash->{xmlrpc}{results} = \@results;
297    } else {
298        $c->forward('/end');
299    }
300}
301
302=head1 AUTHOR
303
304Olivier Thauvin
305
306=head1 LICENSE
307
308This library is free software. You can redistribute it and/or modify
309it under the same terms as Perl itself.
310
311=cut
312
313__PACKAGE__->meta->make_immutable;
314
3151;
Note: See TracBrowser for help on using the repository browser.