]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm
added copy_count methods
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher / metabib.pm
1 package OpenILS::Application::Storage::Publisher::metabib;
2 use base qw/OpenILS::Application::Storage::Publisher/;
3 use vars qw/$VERSION/;
4 use OpenSRF::EX qw/:try/;
5 use OpenILS::Application::Storage::FTS;
6 use OpenILS::Utils::Fieldmapper;
7 use OpenSRF::Utils::Logger qw/:level/;
8 use OpenSRF::Utils::Cache;
9 use Data::Dumper;
10 use Digest::MD5 qw/md5_hex/;
11
12 my $log = 'OpenSRF::Utils::Logger';
13
14 $VERSION = 1;
15
16 sub metarecord_copy_count {
17         my $self = shift;
18         my $client = shift;
19
20         my %args = @_;
21
22         my $sm_table = metabib::metarecord_source_map->table;
23         my $cn_table = asset::call_number->table;
24         my $cp_table = asset::copy->table;
25         my $out_table = actor::org_unit_type->table;
26         my $descendants = "actor.org_unit_descendants(u.id)";
27         my $ancestors = "actor.org_unit_ancestors(?)";
28
29         my $sql = <<"   SQL";
30                 SELECT  t.depth,
31                         u.id AS org_unit,
32                         sum(
33                                 (SELECT count(cp.id)
34                                   FROM  $sm_table r
35                                         JOIN $cn_table cn ON (cn.record = r.source)
36                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
37                                         JOIN $descendants a ON (cp.circ_lib = a.id)
38                                   WHERE r.metarecord = ?)
39                         ) AS count
40                   FROM  $ancestors u
41                         JOIN $out_table t ON (u.ou_type = t.id)
42                   GROUP BY 1,2
43         SQL
44
45         my $sth = metabib::metarecord_source_map->db_Main->prepare_cached($sql);
46         $sth->execute(''.$args{metarecord}, ''.$args{org_unit});
47         while ( my $row = $sth->fetchrow_hashref ) {
48                 $client->respond( $row );
49         }
50         return undef;
51 }
52 __PACKAGE__->register_method(
53         api_name        => 'open-ils.storage.metabib.metarecord.copy_count',
54         method          => 'metarecord_copy_count',
55         api_level       => 1,
56         stream          => 1,
57         cachable        => 1,
58 );
59
60 sub search_full_rec {
61         my $self = shift;
62         my $client = shift;
63
64         my %args = @_;
65         
66         my $term = $args{term};
67         my $limiters = $args{restrict};
68
69         my ($index_col) = metabib::full_rec->columns('FTS');
70         $index_col ||= 'value';
71         my $search_table = metabib::full_rec->table;
72
73         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value',"$index_col");
74
75         my $fts_where = $fts->sql_where_clause();
76         my @fts_ranks = $fts->fts_rank;
77
78         my $rank = join(' + ', @fts_ranks);
79
80         my @binds;
81         my @wheres;
82         for my $limit (@$limiters) {
83                 push @wheres, "( tag = ? AND subfield LIKE ? AND $fts_where )";
84                 push @binds, $$limit{tag}, $$limit{subfield};
85                 $log->debug("Limiting query using { tag => $$limit{tag}, subfield => $$limit{subfield} }", DEBUG);
86         }
87         my $where = join(' OR ', @wheres);
88
89         my $select = "SELECT record, sum($rank) FROM $search_table WHERE $where GROUP BY 1 ORDER BY 2 DESC;";
90
91         $log->debug("Search SQL :: [$select]",DEBUG);
92
93         my $recs = metabib::full_rec->db_Main->selectall_arrayref($select, {}, @binds);
94         $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
95
96         $client->respond($_) for (@$recs);
97         return undef;
98 }
99 __PACKAGE__->register_method(
100         api_name        => 'open-ils.storage.direct.metabib.full_rec.search_fts.value',
101         method          => 'search_full_rec',
102         api_level       => 1,
103         stream          => 1,
104         cachable        => 1,
105 );
106 __PACKAGE__->register_method(
107         api_name        => 'open-ils.storage.direct.metabib.full_rec.search_fts.index_vector',
108         method          => 'search_full_rec',
109         api_level       => 1,
110         stream          => 1,
111         cachable        => 1,
112 );
113
114
115 # XXX factored most of the PG dependant stuff out of here... need to find a way to do "dependants".
116 sub search_class_fts {
117         my $self = shift;
118         my $client = shift;
119         my %args = @_;
120         
121         my $term = $args{term};
122         my $ou = $args{org_unit};
123         my $ou_type = $args{depth};
124
125
126         my $descendants = defined($ou_type) ?
127                                 "actor.org_unit_descendants($ou, $ou_type)" :
128                                 "actor.org_unit_descendants($ou)";
129
130         my $class = $self->{cdbi};
131         my $search_table = $class->table;
132
133         my $metabib_metarecord_source_map_table = metabib::metarecord_source_map->table;
134         my $asset_call_number_table = asset::call_number->table;
135
136         my ($index_col) = $class->columns('FTS');
137         $index_col ||= 'value';
138
139         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value', "$index_col");
140
141         my $fts_where = $fts->sql_where_clause;
142         my @fts_ranks = $fts->fts_rank;
143
144         my $rank = join(' + ', @fts_ranks);
145
146         my $select = <<"        SQL";
147                 SELECT  m.metarecord, sum($rank)/count(m.source)
148                   FROM  $search_table f,
149                         $metabib_metarecord_source_map_table m,
150                         $asset_call_number_table cn,
151                         $descendants d
152                   WHERE $fts_where
153                         AND m.source = f.source
154                         AND cn.record = m.source
155                         AND cn.owning_lib = d.id
156                   GROUP BY 1
157                   ORDER BY 2 DESC;
158         SQL
159
160         $log->debug("Field Search SQL :: [$select]",DEBUG);
161
162         my $recs = $class->db_Main->selectall_arrayref($select);
163         
164         $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
165
166         $client->respond($_) for (@$recs);
167         return undef;
168 }
169 __PACKAGE__->register_method(
170         api_name        => 'open-ils.storage.metabib.title.search_fts.metarecord',
171         method          => 'search_class_fts',
172         api_level       => 1,
173         stream          => 1,
174         cdbi            => 'metabib::title_field_entry',
175         cachable        => 1,
176 );
177 __PACKAGE__->register_method(
178         api_name        => 'open-ils.storage.metabib.author.search_fts.metarecord',
179         method          => 'search_class_fts',
180         api_level       => 1,
181         stream          => 1,
182         cdbi            => 'metabib::author_field_entry',
183         cachable        => 1,
184 );
185 __PACKAGE__->register_method(
186         api_name        => 'open-ils.storage.metabib.subject.search_fts.metarecord',
187         method          => 'search_class_fts',
188         api_level       => 1,
189         stream          => 1,
190         cdbi            => 'metabib::subject_field_entry',
191         cachable        => 1,
192 );
193 __PACKAGE__->register_method(
194         api_name        => 'open-ils.storage.metabib.keyword.search_fts.metarecord',
195         method          => 'search_class_fts',
196         api_level       => 1,
197         stream          => 1,
198         cdbi            => 'metabib::keyword_field_entry',
199         cachable        => 1,
200 );
201
202 # XXX factored most of the PG dependant stuff out of here... need to find a way to do "dependants".
203 sub search_class_fts_count {
204         my $self = shift;
205         my $client = shift;
206         my %args = @_;
207         
208         my $term = $args{term};
209         my $ou = $args{org_unit};
210         my $ou_type = $args{depth};
211         my $limit = $args{limit} || 100;
212         my $offset = $args{offset} || 0;
213
214         my $descendants = defined($ou_type) ?
215                                 "actor.org_unit_descendants($ou, $ou_type)" :
216                                 "actor.org_unit_descendants($ou)";
217                 
218
219         (my $search_class = $self->api_name) =~ s/.*metabib.(\w+).search_fts.*/$1/o;
220         my $cache_key = md5_hex($search_class.$term.$ou.$ou_type.'_COUNT_');
221
222         my $cached_recs = OpenSRF::Utils::Cache->new->get_cache( $cache_key );
223         return $cached_recs if (defined $cached_recs);
224
225         my $class = $self->{cdbi};
226         my $search_table = $class->table;
227
228         my $metabib_metarecord_source_map_table = metabib::metarecord_source_map->table;
229         my $asset_call_number_table = asset::call_number->table;
230
231         my ($index_col) = $class->columns('FTS');
232         $index_col ||= 'value';
233
234         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value',"$index_col");
235
236         my $fts_where = $fts->sql_where_clause;
237
238         # XXX test an "EXISTS version of descendant checking...
239         my $select = <<"        SQL";
240                 SELECT  count(distinct  m.metarecord)
241                   FROM  $search_table f,
242                         $metabib_metarecord_source_map_table m,
243                         $asset_call_number_table cn,
244                         $descendants d
245                   WHERE $fts_where
246                         AND m.source = f.source
247                         AND cn.record = m.source
248                         AND cn.owning_lib = d.id;
249         SQL
250
251         $log->debug("Field Search Count SQL :: [$select]",DEBUG);
252
253         my $recs = $class->db_Main->selectrow_arrayref($select)->[0];
254         
255         $log->debug("Count Search yielded $recs results.",DEBUG);
256
257         OpenSRF::Utils::Cache->new->put_cache( $cache_key => $recs );
258
259         return $recs;
260
261 }
262 __PACKAGE__->register_method(
263         api_name        => 'open-ils.storage.metabib.title.search_fts.metarecord_count',
264         method          => 'search_class_fts_count',
265         api_level       => 1,
266         stream          => 1,
267         cdbi            => 'metabib::title_field_entry',
268         cachable        => 1,
269 );
270 __PACKAGE__->register_method(
271         api_name        => 'open-ils.storage.metabib.author.search_fts.metarecord_count',
272         method          => 'search_class_fts_count',
273         api_level       => 1,
274         stream          => 1,
275         cdbi            => 'metabib::author_field_entry',
276         cachable        => 1,
277 );
278 __PACKAGE__->register_method(
279         api_name        => 'open-ils.storage.metabib.subject.search_fts.metarecord_count',
280         method          => 'search_class_fts_count',
281         api_level       => 1,
282         stream          => 1,
283         cdbi            => 'metabib::subject_field_entry',
284         cachable        => 1,
285 );
286 __PACKAGE__->register_method(
287         api_name        => 'open-ils.storage.metabib.keyword.search_fts.metarecord_count',
288         method          => 'search_class_fts_count',
289         api_level       => 1,
290         stream          => 1,
291         cdbi            => 'metabib::keyword_field_entry',
292         cachable        => 1,
293 );
294
295 1;