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