]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/authority.pm
adding open-ils.search support from subject crossreferencing
[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 $class = $self->api_name) =~ s/^.+authority.([^\.]+)\.see.+$/$1/o;
100
101         my @marc = $self->method_lookup('open-ils.storage.authority.search.marc')
102                         ->run( term => $term, tag => '4%', subfield => 'a' );
103         for my $m ( @marc ) {
104                 my $doc = $parser->parse_string($m);
105                 my @nodes = $doc->documentElement->findnodes('//*[substring(@tag,1,1)="1"]/*');
106                 my $list = [ map { $_->textContent } @nodes ];
107                 $client->respond( $list ) if (_empty_check($$list[0], "metabib::${class}_field_entry"));
108         }
109         return undef;
110 }
111 for my $class ( qw/title author subject keyword series/ ) {
112         __PACKAGE__->register_method(
113                 api_name        => "open-ils.storage.authority.$class.see_from.controlled",
114                 method          => 'find_see_from_controlled',
115                 api_level       => 1,
116                 stream          => 1,
117                 cachable        => 1,
118         );
119 }
120
121 sub find_see_also_from_controlled {
122         my $self = shift;
123         my $client = shift;
124         my $term = shift;
125
126         (my $class = $self->api_name) =~ s/^.+authority.([^\.]+)\.see.+$/$1/o;
127
128         my @marc = $self->method_lookup('open-ils.storage.authority.search.marc')
129                         ->run( term => $term, tag => '5%', subfield => 'a' );
130         for my $m ( @marc ) {
131                 my $doc = $parser->parse_string($m);
132                 my @nodes = $doc->documentElement->findnodes('//*[substring(@tag,1,1)="1"]/*');
133                 my $list = [ map { $_->textContent } @nodes ];
134                 $client->respond( $list ) if (_empty_check($$list[0], "metabib::${class}_field_entry"));
135         }
136         return undef;
137 }
138 for my $class ( qw/title author subject keyword series/ ) {
139         __PACKAGE__->register_method(
140                 api_name        => "open-ils.storage.authority.$class.see_also_from.controlled",
141                 method          => 'find_see_also_from_controlled',
142                 api_level       => 1,
143                 stream          => 1,
144                 cachable        => 1,
145         );
146 }
147
148
149 1;