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