860a8f5cad241901c42e0c5895fdbc8dd7e909f8
[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
28         my $tag_where = "AND f.tag LIKE '$tag'";
29         if (ref $tag) {
30                 $tag_where = "AND f.tag IN ('".join("','",@$tag)."')";
31         }
32
33         my $sf_where = "AND f.subfield = '$subfield'";
34         if (ref $subfield) {
35                 $sf_where = "AND f.subfield IN ('".join("','",@$subfield)."')";
36         }
37
38         my $search_table = authority::full_rec->table;
39         my $marc_table = authority::record_entry->table;
40
41         my ($index_col) = authority::full_rec->columns('FTS');
42         $index_col ||= 'value';
43
44         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'f.value', "f.$index_col");
45
46         my $fts_where = $fts->sql_where_clause;
47         my $fts_words = join '%', $fts->words;
48         my $fts_words_where = "f.value LIKE '$fts_words\%'";
49
50
51         my $select = <<"        SQL";
52                 SELECT  DISTINCT a.marc
53                 FROM    $search_table f,
54                         $marc_table a
55                 WHERE   $fts_where
56                         -- AND $fts_words_where
57                         $tag_where
58                         $sf_where
59                         AND a.id = f.record
60         SQL
61
62         $log->debug("Authority Search SQL :: [$select]",DEBUG);
63
64         my $recs = authority::full_rec->db_Main->selectcol_arrayref( $select );
65         
66         $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
67
68         $client->respond($_) for (@$recs);
69         return undef;
70 }
71 __PACKAGE__->register_method(
72         api_name        => "open-ils.storage.authority.search.marc",
73         method          => 'find_authority_marc',
74         api_level       => 1,
75         stream          => 1,
76         cachable        => 1,
77 );
78
79 sub _empty_check {
80         my $term = shift;
81         my $class = shift || 'metabib::full_rec';
82
83         my $table = $class->table;
84
85         my ($index_col) = $class->columns('FTS');
86         $index_col ||= 'value';
87
88         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'm.value', "m.$index_col");
89         my $fts_where = $fts->sql_where_clause;
90
91         my $sql = <<"   SQL";
92                 SELECT  TRUE
93                 FROM    $table m
94                 WHERE   $fts_where
95                 LIMIT 1
96         SQL
97
98         return $class->db_Main->selectcol_arrayref($sql)->[0];
99 }
100
101 sub find_see_from_controlled {
102         my $self = shift;
103         my $client = shift;
104         my $term = shift;
105
106         (my $class = $self->api_name) =~ s/^.+authority.([^\.]+)\.see.+$/$1/o;
107         my $sf = 'a';
108         $sf = 't' if ($class eq 'title');
109
110         my @marc = $self->method_lookup('open-ils.storage.authority.search.marc')
111                         ->run( term => $term, tag => '4%', subfield => $sf );
112         for my $m ( @marc ) {
113                 my $doc = $parser->parse_string($m);
114                 my @nodes = $doc->documentElement->findnodes('//*[substring(@tag,1,1)="1"]/*[@code="a" or @code="d" or @code="x"]');
115                 my $list = [ map { $_->textContent } @nodes ];
116                 $client->respond( $list ) if (_empty_check($$list[0], "metabib::${class}_field_entry"));
117         }
118         return undef;
119 }
120 for my $class ( qw/title author subject keyword series/ ) {
121         __PACKAGE__->register_method(
122                 api_name        => "open-ils.storage.authority.$class.see_from.controlled",
123                 method          => 'find_see_from_controlled',
124                 api_level       => 1,
125                 stream          => 1,
126                 cachable        => 1,
127         );
128 }
129
130 sub find_see_also_from_controlled {
131         my $self = shift;
132         my $client = shift;
133         my $term = shift;
134
135         (my $class = $self->api_name) =~ s/^.+authority.([^\.]+)\.see.+$/$1/o;
136         my $sf = 'a';
137         $sf = 't' if ($class eq 'title');
138
139         my @marc = $self->method_lookup('open-ils.storage.authority.search.marc')
140                         ->run( term => $term, tag => '5%', subfield => $sf );
141         for my $m ( @marc ) {
142                 my $doc = $parser->parse_string($m);
143                 my @nodes = $doc->documentElement->findnodes('//*[substring(@tag,1,1)="1"]/*[@code="a" or @code="d" or @code="x"]');
144                 my $list = [ map { $_->textContent } @nodes ];
145                 $client->respond( $list ) if (_empty_check($$list[0], "metabib::${class}_field_entry"));
146         }
147         return undef;
148 }
149 for my $class ( qw/title author subject keyword series/ ) {
150         __PACKAGE__->register_method(
151                 api_name        => "open-ils.storage.authority.$class.see_also_from.controlled",
152                 method          => 'find_see_also_from_controlled',
153                 api_level       => 1,
154                 stream          => 1,
155                 cachable        => 1,
156         );
157 }
158
159
160 1;