]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/authority.pm
allowing "limit" (and "offset") to be passed into authority marc search and ordering...
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher / authority.pm
1 package OpenILS::Application::Storage::Publisher::authority;
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 use XML::LibXML;
12
13 my $log = 'OpenSRF::Utils::Logger';
14
15 $VERSION = 1;
16
17 my $parser = XML::LibXML->new;
18
19 sub find_authority_marc {
20         my $self = shift;
21         my $client = shift;
22         my %args = @_;
23         
24         my $term = $args{term};
25         my $tag = $args{tag};
26         my $subfield = $args{subfield};
27         my $limit = $args{limit} || 100;
28         my $offset = $args{offset} || 0;
29
30         if ($limit) {
31                 $limit = "LIMIT $limit";
32         } else {
33                 $limit = '';
34         }
35
36         if ($offset) {
37                 $offset = "OFFSET $offset";
38         } else {
39                 $offset = '';
40         }
41
42         my $tag_where = "AND f.tag LIKE '$tag'";
43         if (ref $tag) {
44                 $tag_where = "AND f.tag IN ('".join("','",@$tag)."')";
45         }
46
47         my $sf_where = "AND f.subfield = '$subfield'";
48         if (ref $subfield) {
49                 $sf_where = "AND f.subfield IN ('".join("','",@$subfield)."')";
50         }
51
52         my $search_table = authority::full_rec->table;
53         my $marc_table = authority::record_entry->table;
54
55         my ($index_col) = authority::full_rec->columns('FTS');
56         $index_col ||= 'value';
57
58         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'f.value', "f.$index_col");
59
60
61         my $fts_where = $fts->sql_where_clause;
62         my $fts_words = join '%', $fts->words;
63         my $fts_words_where = "f.value LIKE '$fts_words\%'";
64
65         my $fts_rank = join '+', $fts->fts_rank;
66
67         my $select = <<"        SQL";
68                 SELECT  a.marc, sum($fts_rank)
69                 FROM    $search_table f,
70                         $marc_table a
71                 WHERE   $fts_where
72                         -- AND $fts_words_where
73                         $tag_where
74                         $sf_where
75                         AND a.id = f.record
76                         GROUP BY 1
77                         ORDER BY 2
78                         $limit
79                         $offset
80                         
81         SQL
82
83         $log->debug("Authority Search SQL :: [$select]",DEBUG);
84
85         my $recs = authority::full_rec->db_Main->selectcol_arrayref( $select );
86         
87         $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
88
89         $client->respond($_) for (@$recs);
90         return undef;
91 }
92 __PACKAGE__->register_method(
93         api_name        => "open-ils.storage.authority.search.marc",
94         method          => 'find_authority_marc',
95         api_level       => 1,
96         stream          => 1,
97         cachable        => 1,
98 );
99
100 sub _empty_check {
101         my $term = shift;
102         my $class = shift || 'metabib::full_rec';
103
104         my $table = $class->table;
105
106         my ($index_col) = $class->columns('FTS');
107         $index_col ||= 'value';
108
109         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'm.value', "m.$index_col");
110         my $fts_where = $fts->sql_where_clause;
111
112         my $sql = <<"   SQL";
113                 SELECT  TRUE
114                 FROM    $table m
115                 WHERE   $fts_where
116                 LIMIT 1
117         SQL
118
119         return $class->db_Main->selectcol_arrayref($sql)->[0];
120 }
121
122 sub find_see_from_controlled {
123         my $self = shift;
124         my $client = shift;
125         my $term = shift;
126         my $limit = shift;
127         my $offset = shift;
128
129         (my $class = $self->api_name) =~ s/^.+authority.([^\.]+)\.see.+$/$1/o;
130         my $sf = 'a';
131         $sf = 't' if ($class eq 'title');
132
133         my @marc = $self->method_lookup('open-ils.storage.authority.search.marc')
134                         ->run( term => $term, tag => '4%', subfield => $sf, limit => $limit, offset => $offset );
135         for my $m ( @marc ) {
136                 my $doc = $parser->parse_string($m);
137                 my @nodes = $doc->documentElement->findnodes('//*[substring(@tag,1,1)="1"]/*[@code="a" or @code="d" or @code="x"]');
138                 my $list = [ map { $_->textContent } @nodes ];
139                 $client->respond( $list ) if (_empty_check(join(' ',@$list), "metabib::${class}_field_entry"));
140         }
141         return undef;
142 }
143 for my $class ( qw/title author subject keyword series/ ) {
144         __PACKAGE__->register_method(
145                 api_name        => "open-ils.storage.authority.$class.see_from.controlled",
146                 method          => 'find_see_from_controlled',
147                 api_level       => 1,
148                 stream          => 1,
149                 cachable        => 1,
150         );
151 }
152
153 sub find_see_also_from_controlled {
154         my $self = shift;
155         my $client = shift;
156         my $term = shift;
157         my $limit = shift;
158         my $offset = shift;
159
160         (my $class = $self->api_name) =~ s/^.+authority.([^\.]+)\.see.+$/$1/o;
161         my $sf = 'a';
162         $sf = 't' if ($class eq 'title');
163
164         my @marc = $self->method_lookup('open-ils.storage.authority.search.marc')
165                         ->run( term => $term, tag => '5%', subfield => $sf, limit => $limit, offset => $offset );
166         for my $m ( @marc ) {
167                 my $doc = $parser->parse_string($m);
168                 my @nodes = $doc->documentElement->findnodes('//*[substring(@tag,1,1)="1"]/*[@code="a" or @code="d" or @code="x"]');
169                 my $list = [ map { $_->textContent } @nodes ];
170                 $client->respond( $list ) if (_empty_check(join(' ',@$list), "metabib::${class}_field_entry"));
171         }
172         return undef;
173 }
174 for my $class ( qw/title author subject keyword series/ ) {
175         __PACKAGE__->register_method(
176                 api_name        => "open-ils.storage.authority.$class.see_also_from.controlled",
177                 method          => 'find_see_also_from_controlled',
178                 api_level       => 1,
179                 stream          => 1,
180                 cachable        => 1,
181         );
182 }
183
184
185 1;