]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0476.schema.authority_normalize_heading.sql
LP#1838995: (follow-up) adjust ID for new permission
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0476.schema.authority_normalize_heading.sql
1 -- Use spi_prepare/spi_exec_query to delegate escaping issues to the database
2 -- (where they belong) and avoid ugly MARC corner cases
3 BEGIN;
4
5 INSERT INTO config.upgrade_log (version) VALUES ('0476'); -- dbs
6
7 CREATE OR REPLACE FUNCTION authority.normalize_heading( TEXT ) RETURNS TEXT AS $func$
8     use strict;
9     use warnings;
10
11     use utf8;
12     use MARC::Record;
13     use MARC::File::XML (BinaryEncoding => 'UTF8');
14     use UUID::Tiny ':std';
15
16     my $xml = shift() or return undef;
17
18     my $r;
19
20     # Prevent errors in XML parsing from blowing out ungracefully
21     eval {
22         $r = MARC::Record->new_from_xml( $xml );
23         1;
24     } or do {
25        return 'BAD_MARCXML_' . create_uuid_as_string(UUID_MD5, $xml);
26     };
27
28     if (!$r) {
29        return 'BAD_MARCXML_' . create_uuid_as_string(UUID_MD5, $xml);
30     }
31
32     # From http://www.loc.gov/standards/sourcelist/subject.html
33     my $thes_code_map = {
34         a => 'lcsh',
35         b => 'lcshac',
36         c => 'mesh',
37         d => 'nal',
38         k => 'cash',
39         n => 'notapplicable',
40         r => 'aat',
41         s => 'sears',
42         v => 'rvm',
43     };
44
45     # Default to "No attempt to code" if the leader is horribly broken
46     my $fixed_field = $r->field('008');
47     my $thes_char = '|';
48     if ($fixed_field) { 
49         $thes_char = substr($fixed_field->data(), 11, 1) || '|';
50     }
51
52     my $thes_code = 'UNDEFINED';
53
54     if ($thes_char eq 'z') {
55         # Grab the 040 $f per http://www.loc.gov/marc/authority/ad040.html
56         $thes_code = $r->subfield('040', 'f') || 'UNDEFINED';
57     } elsif ($thes_code_map->{$thes_char}) {
58         $thes_code = $thes_code_map->{$thes_char};
59     }
60
61     my $auth_txt = '';
62     my $head = $r->field('1..');
63     if ($head) {
64         # Concatenate all of these subfields together, prefixed by their code
65         # to prevent collisions along the lines of "Fiction, North Carolina"
66         foreach my $sf ($head->subfields()) {
67             $auth_txt .= '‡' . $sf->[0] . ' ' . $sf->[1];
68         }
69     }
70     
71     if ($auth_txt) {
72         my $stmt = spi_prepare('SELECT public.naco_normalize($1) AS norm_text', 'TEXT');
73         my $result = spi_exec_prepared($stmt, $auth_txt);
74         my $norm_txt = $result->{rows}[0]->{norm_text};
75         spi_freeplan($stmt);
76         undef($stmt);
77         return $head->tag() . "_" . $thes_code . " " . $norm_txt;
78     }
79
80     return 'NOHEADING_' . $thes_code . ' ' . create_uuid_as_string(UUID_MD5, $xml);
81 $func$ LANGUAGE 'plperlu' IMMUTABLE;
82
83 COMMIT;