]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/asset.pm
fixing worst-case for "global" search, adding page up and down
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher / asset.pm
1 package OpenILS::Application::Storage::Publisher::asset;
2 use base qw/OpenILS::Application::Storage/;
3 #use OpenILS::Application::Storage::CDBI::asset;
4 #use OpenSRF::Utils::Logger qw/:level/;
5 #use OpenILS::Utils::Fieldmapper;
6 #
7 #my $log = 'OpenSRF::Utils::Logger';
8
9 # XXX
10 # see /home/miker/cn_browse-test.sql for page up and down sql ...
11 # XXX
12
13 sub cn_browse_pagedown {
14         my $self = shift;
15         my $client = shift;
16
17         my %args = @_;
18
19         my $cn = uc($args{label});
20         my $org = $args{org_unit};
21         my $depth = $args{depth};
22         my $boundry_id = $args{boundry_id};
23         my $size = $args{page_size} || 20;
24         $size = int($size);
25
26         my $table = asset::call_number->table;
27
28         my $descendants = "actor.org_unit_descendants($org)";
29         if (defined $depth) {
30                 $descendants = "actor.org_unit_descendants($org,$depth)";
31         }
32
33         my $sql = <<"   SQL";
34                 select * from (
35                         select
36                                 cn.label,
37                                 cn.owning_lib,
38                                 cn.record,
39                                 cn.id
40                         from
41                                 $table cn
42                                 join $descendants d
43                                         on (d.id = cn.owning_lib)
44                         where
45                                 upper(label) > ?
46                                 or ( cn.id > ? and upper(label) = ? )
47                         order by upper(label)
48                         limit 1000
49                 ) as foo
50                 order by 1,4
51                 limit $size;
52         SQL
53
54         my $sth = asset::call_number->db_Main->prepare($sql);
55         $sth->execute($cn, $boundry_id, $cn);
56         while ( my $row = $sth->fetchrow_hashref ) {
57                 $client->respond($row);
58         }
59         $sth->finish;
60
61         return undef;
62 }
63 __PACKAGE__->register_method(
64         method          => 'cn_browse_pagedown',
65         api_name        => 'open-ils.storage.asset.call_number.browse.page_down',
66         argc            => 4,
67         stream          => 1,
68 );
69
70 sub cn_browse_pageup {
71         my $self = shift;
72         my $client = shift;
73
74         my %args = @_;
75
76         my $cn = uc($args{label});
77         my $org = $args{org_unit};
78         my $depth = $args{depth};
79         my $boundry_id = $args{boundry_id};
80         my $size = $args{page_size} || 20;
81         $size = int($size);
82
83         my $table = asset::call_number->table;
84
85         my $descendants = "actor.org_unit_descendants($org)";
86         if (defined $depth) {
87                 $descendants = "actor.org_unit_descendants($org,$depth)";
88         }
89
90         my $sql = <<"   SQL";
91                 select * from (
92                         select * from (
93                                 select
94                                         cn.label,
95                                         cn.owning_lib,
96                                         cn.record,
97                                         cn.id
98                                 from
99                                         $table cn
100                                         join $descendants d
101                                                 on (d.id = cn.owning_lib)
102                                 where
103                                         upper(label) < ?
104                                         or ( cn.id < ? and upper(label) = ? )
105                                 order by upper(label) desc
106                                 limit 1000
107                         ) as foo
108                         order by 1 desc, 4 desc
109                         limit $size
110                 ) as bar
111                 order by 1,4;
112         SQL
113
114         my $sth = asset::call_number->db_Main->prepare($sql);
115         $sth->execute($cn, $boundry_id, $cn);
116         while ( my $row = $sth->fetchrow_hashref ) {
117                 $client->respond($row);
118         }
119         $sth->finish;
120
121         return undef;
122 }
123 __PACKAGE__->register_method(
124         method          => 'cn_browse_pageup',
125         api_name        => 'open-ils.storage.asset.call_number.browse.page_up',
126         argc            => 4,
127         stream          => 1,
128 );
129
130 sub cn_browse_target {
131         my $self = shift;
132         my $client = shift;
133
134         my %args = @_;
135
136         my $cn = uc($args{label});
137         my $org = $args{org_unit};
138         my $depth = $args{depth};
139         my $size = $args{page_size} || 20;
140         $size /= 2;
141         $size = int($size);
142
143         my $table = asset::call_number->table;
144
145         my $descendants = "actor.org_unit_descendants($org)";
146         if (defined $depth) {
147                 $descendants = "actor.org_unit_descendants($org,$depth)";
148         }
149
150         my $top_sql = <<"       SQL";
151                 select * from (
152                         select * from (
153                                 select
154                                         cn.label,
155                                         cn.owning_lib,
156                                         cn.record,
157                                         cn.id
158                                 from
159                                         $table cn
160                                         join $descendants d
161                                                 on (d.id = cn.owning_lib)
162                                 where
163                                         upper(label) < ?
164                                 order by upper(label) desc
165                                 limit 1000
166                         ) as foo
167                         order by 1 desc, 4 desc
168                         limit $size
169                 ) as bar
170                 order by 1,4;
171         SQL
172
173         my $bottom_sql = <<"    SQL";
174                 select * from (
175                         select
176                                 cn.label,
177                                 cn.owning_lib,
178                                 cn.record,
179                                 cn.id
180                         from
181                                 $table cn
182                                 join $descendants d
183                                         on (d.id = cn.owning_lib)
184                         where
185                                 upper(label) >= ?
186                         order by upper(label)
187                         limit 1000
188                 ) as foo
189                 order by 1,4
190                 limit $size;
191         SQL
192
193         my $sth = asset::call_number->db_Main->prepare($top_sql);
194         $sth->execute($cn);
195         while ( my $row = $sth->fetchrow_hashref ) {
196                 $client->respond($row);
197         }
198         $sth->finish;
199
200         $sth = asset::call_number->db_Main->prepare($bottom_sql);
201         $sth->execute($cn);
202         while ( my $row = $sth->fetchrow_hashref ) {
203                 $client->respond($row);
204         }
205         $sth->finish;
206
207         return undef;
208 }
209 __PACKAGE__->register_method(
210         method          => 'cn_browse_target',
211         api_name        => 'open-ils.storage.asset.call_number.browse.target',
212         argc            => 4,
213         stream          => 1,
214 );
215
216
217 sub copy_proximity {
218         my $self = shift;
219         my $client = shift;
220
221         my $cp = shift;
222         my $org = shift;
223
224         return unless ($cp && $org);
225
226         $cp = $cp->id if (ref $cp);
227         $cp = asset::copy->retrieve($cp);
228         return 999 unless $copy;
229         my $ol = $cp->call_number->owning_lib;
230
231         return asset::copy->db_Main->selectcol_arrayref('SELECT actor.org_unit_proximity(?,?)',{},"$ol","$org")->[0];
232 }
233 __PACKAGE__->register_method(
234         method          => 'copy_proximity',
235         api_name        => 'open-ils.storage.asset.copy.proximity',
236         argc            => 2,
237         stream          => 1,
238 );
239
240 sub asset_copy_location_all {
241         my $self = shift;
242         my $client = shift;
243
244         for my $rec ( asset::copy_location->retrieve_all ) {
245                 $client->respond( $rec->to_fieldmapper );
246         }
247
248         return undef;
249 }
250 __PACKAGE__->register_method(
251         method          => 'asset_copy_location_all',
252         api_name        => 'open-ils.storage.direct.asset.copy_location.retrieve.all',
253         argc            => 0,
254         stream          => 1,
255 );
256
257 sub fleshed_copy {
258         my $self = shift;
259         my $client = shift;
260         my @ids = @_;
261
262         return undef unless (@ids);
263
264         @ids = ($ids[0]) unless ($self->api_name =~ /batch/o);
265
266         for my $id ( @ids ) {
267                 next unless $id;
268                 my $cp = asset::copy->retrieve($id);
269
270                 my $cp_fm = $cp->to_fieldmapper;
271                 $cp_fm->circ_lib( $cp->circ_lib->to_fieldmapper );
272                 $cp_fm->location( $cp->location->to_fieldmapper );
273                 $cp_fm->status( $cp->status->to_fieldmapper );
274                 $cp_fm->stat_cat_entries( [ map { $_->to_fieldmapper } $cp->stat_cat_entries ] );
275
276                 $client->respond( $cp_fm );
277         }
278
279         return undef;
280 }
281 __PACKAGE__->register_method(
282         api_name        => 'open-ils.storage.fleshed.asset.copy.batch.retrieve',
283         method          => 'fleshed_copy',
284         argc            => 1,
285         stream          => 1,
286 );
287 __PACKAGE__->register_method(
288         api_name        => 'open-ils.storage.fleshed.asset.copy.retrieve',
289         method          => 'fleshed_copy',
290         argc            => 1,
291 );
292
293 sub fleshed_copy_by_barcode {
294         my $self = shift;
295         my $client = shift;
296         my $bc = ''.shift;
297
298         my ($cp) = asset::copy->search( { barcode => $bc } );
299
300         return undef unless ($cp);
301
302         my $cp_fm = $cp->to_fieldmapper;
303         $cp_fm->circ_lib( $cp->circ_lib->to_fieldmapper );
304         $cp_fm->location( $cp->location->to_fieldmapper );
305         $cp_fm->status( $cp->status->to_fieldmapper );
306
307         return $cp_fm;
308 }       
309 __PACKAGE__->register_method(
310         api_name        => 'open-ils.storage.fleshed.asset.copy.search.barcode',
311         method          => 'fleshed_copy_by_barcode',
312         argc            => 1,
313         stream          => 1,
314 );
315
316 #XXX Fix stored proc calls
317 sub ranged_asset_stat_cat {
318         my $self = shift;
319         my $client = shift;
320         my $ou = ''.shift();
321
322         return undef unless ($ou);
323         my $s_table = asset::stat_cat->table;
324
325         my $select = <<"        SQL";
326                 SELECT  s.*
327                   FROM  $s_table s
328                         JOIN actor.org_unit_full_path(?) p ON (p.id = s.owner)
329                   ORDER BY name
330         SQL
331
332         $fleshed = 0;
333         $fleshed = 1 if ($self->api_name =~ /fleshed/o);
334
335         my $sth = asset::stat_cat->db_Main->prepare_cached($select);
336         $sth->execute($ou);
337
338         for my $sc ( map { asset::stat_cat->construct($_) } $sth->fetchall_hash ) {
339                 my $sc_fm = $sc->to_fieldmapper;
340                 $sc_fm->entries(
341                         [ $self->method_lookup( 'open-ils.storage.ranged.asset.stat_cat_entry.search.stat_cat' )->run($ou,$sc->id) ]
342                 ) if ($fleshed);
343                 $client->respond( $sc_fm );
344         }
345
346         return undef;
347 }
348 __PACKAGE__->register_method(
349         api_name        => 'open-ils.storage.ranged.fleshed.asset.stat_cat.all',
350         api_level       => 1,
351         stream          => 1,
352         method          => 'ranged_asset_stat_cat',
353 );
354
355 __PACKAGE__->register_method(
356         api_name        => 'open-ils.storage.ranged.asset.stat_cat.all',
357         api_level       => 1,
358         stream          => 1,
359         method          => 'ranged_asset_stat_cat',
360 );
361
362
363 #XXX Fix stored proc calls
364 sub multiranged_asset_stat_cat {
365         my $self = shift;
366         my $client = shift;
367         my $ous = shift;
368
369         return undef unless (defined($ous) and @$ous);
370         my $s_table = asset::stat_cat->table;
371
372         my $select = <<"        SQL";
373                 SELECT  s.*
374                   FROM  $s_table s
375                   WHERE s.owner IN ( XXX )
376                   ORDER BY name
377         SQL
378
379         my $collector = ' INTERSECT ';
380         my $entry_method = 'open-ils.storage.multiranged.intersect.asset.stat_cat_entry.search.stat_cat';
381         if ($self->api_name =~ /union/o) {
382                 $collector = ' UNION ';
383                 $entry_method = 'open-ils.storage.multiranged.union.asset.stat_cat_entry.search.stat_cat';
384         }
385
386         my $binds = join($collector, map { 'SELECT id FROM actor.org_unit_full_path(?)' } grep {defined} @$ous);
387         $select =~ s/XXX/$binds/so;
388         
389         $fleshed = 0;
390         $fleshed = 1 if ($self->api_name =~ /fleshed/o);
391
392         my $sth = asset::stat_cat->db_Main->prepare_cached($select);
393         $sth->execute(map { "$_" } grep {defined} @$ous);
394
395         for my $sc ( map { asset::stat_cat->construct($_) } $sth->fetchall_hash ) {
396                 my $sc_fm = $sc->to_fieldmapper;
397                 $sc_fm->entries(
398                         [ $self->method_lookup( $entry_method )->run($ous, $sc->id) ]
399                 ) if ($fleshed);
400                 $client->respond( $sc_fm );
401         }
402
403         return undef;
404 }
405 __PACKAGE__->register_method(
406         api_name        => 'open-ils.storage.multiranged.intersect.fleshed.asset.stat_cat.all',
407         api_level       => 1,
408         stream          => 1,
409         method          => 'multiranged_asset_stat_cat',
410 );
411 __PACKAGE__->register_method(
412         api_name        => 'open-ils.storage.multiranged.union.fleshed.asset.stat_cat.all',
413         api_level       => 1,
414         stream          => 1,
415         method          => 'multiranged_asset_stat_cat',
416 );
417
418 #XXX Fix stored proc calls
419 sub ranged_asset_stat_cat_entry {
420         my $self = shift;
421         my $client = shift;
422         my $ou = ''.shift();
423         my $sc = ''.shift();
424
425         return undef unless ($ou);
426         my $s_table = asset::stat_cat_entry->table;
427
428         my $select = <<"        SQL";
429                 SELECT  s.*
430                   FROM  $s_table s
431                         JOIN actor.org_unit_full_path(?) p ON (p.id = s.owner)
432                   WHERE stat_cat = ?
433                   ORDER BY name
434         SQL
435
436         my $sth = asset::stat_cat->db_Main->prepare_cached($select);
437         $sth->execute($ou,$sc);
438
439         for my $sce ( map { asset::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
440                 $client->respond( $sce->to_fieldmapper );
441         }
442
443         return undef;
444 }
445 __PACKAGE__->register_method(
446         api_name        => 'open-ils.storage.ranged.asset.stat_cat_entry.search.stat_cat',
447         api_level       => 1,
448         stream          => 1,
449         method          => 'ranged_asset_stat_cat_entry',
450 );
451
452 #XXX Fix stored proc calls
453 sub multiranged_asset_stat_cat_entry {
454         my $self = shift;
455         my $client = shift;
456         my $ous = shift;
457         my $sc = ''.shift();
458
459         return undef unless (defined($ous) and @$ous);
460         my $s_table = asset::stat_cat_entry->table;
461
462         my $collector = ' INTERSECT ';
463         $collector = ' UNION ' if ($self->api_name =~ /union/o);
464
465         my $select = <<"        SQL";
466                 SELECT  s.*
467                   FROM  $s_table s
468                   WHERE s.owner IN ( XXX ) and s.stat_cat = ?
469                   ORDER BY value
470         SQL
471
472         my $binds = join($collector, map { 'SELECT id FROM actor.org_unit_full_path(?)' } grep {defined} @$ous);
473         $select =~ s/XXX/$binds/so;
474         
475         my $sth = asset::stat_cat->db_Main->prepare_cached($select);
476         $sth->execute(map {"$_"} @$ous,$sc);
477
478         for my $sce ( map { asset::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
479                 $client->respond( $sce->to_fieldmapper );
480         }
481
482         return undef;
483 }
484 __PACKAGE__->register_method(
485         api_name        => 'open-ils.storage.multiranged.intersect.asset.stat_cat_entry.search.stat_cat',
486         api_level       => 1,
487         stream          => 1,
488         method          => 'multiranged_asset_stat_cat_entry',
489 );
490 __PACKAGE__->register_method(
491         api_name        => 'open-ils.storage.multiranged.union.asset.stat_cat_entry.search.stat_cat',
492         api_level       => 1,
493         stream          => 1,
494         method          => 'multiranged_asset_stat_cat_entry',
495 );
496
497
498
499 1;