]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0556.unnest_biblio_extract_metabib_field_entry.sql
LP#1206936 - Fix wrong billing info in money.transaction_billing_summary
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0556.unnest_biblio_extract_metabib_field_entry.sql
1 -- Evergreen DB patch 0556.unnest_biblio_extract_metabib_field_entry.sql
2 --
3 -- Replace usage of custom explode_array() function with native unnest()
4 --
5 BEGIN;
6
7 -- check whether patch can be applied
8 SELECT evergreen.upgrade_deps_block_check('0556', :eg_version);
9
10 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
11 DECLARE
12     bib     biblio.record_entry%ROWTYPE;
13     idx     config.metabib_field%ROWTYPE;
14     xfrm        config.xml_transform%ROWTYPE;
15     prev_xfrm   TEXT;
16     transformed_xml TEXT;
17     xml_node    TEXT;
18     xml_node_list   TEXT[];
19     facet_text  TEXT;
20     raw_text    TEXT;
21     curr_text   TEXT;
22     joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
23     output_row  metabib.field_entry_template%ROWTYPE;
24 BEGIN
25
26     -- Get the record
27     SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
28
29     -- Loop over the indexing entries
30     FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
31
32         SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
33
34         -- See if we can skip the XSLT ... it's expensive
35         IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
36             -- Can't skip the transform
37             IF xfrm.xslt <> '---' THEN
38                 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
39             ELSE
40                 transformed_xml := bib.marc;
41             END IF;
42
43             prev_xfrm := xfrm.name;
44         END IF;
45
46         xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
47
48         raw_text := NULL;
49         FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
50             CONTINUE WHEN xml_node !~ E'^\\s*<';
51
52             curr_text := ARRAY_TO_STRING(
53                 oils_xpath( '//text()',
54                     REGEXP_REPLACE( -- This escapes all &s not followed by "amp;".  Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
55                         REGEXP_REPLACE( -- This escapes embeded <s
56                             xml_node,
57                             $re$(>[^<]+)(<)([^>]+<)$re$,
58                             E'\\1&lt;\\3',
59                             'g'
60                         ),
61                         '&(?!amp;)',
62                         '&amp;',
63                         'g'
64                     )
65                 ),
66                 ' '
67             );
68
69             CONTINUE WHEN curr_text IS NULL OR curr_text = '';
70
71             IF raw_text IS NOT NULL THEN
72                 raw_text := raw_text || joiner;
73             END IF;
74
75             raw_text := COALESCE(raw_text,'') || curr_text;
76
77             -- insert raw node text for faceting
78             IF idx.facet_field THEN
79
80                 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
81                     facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
82                 ELSE
83                     facet_text := curr_text;
84                 END IF;
85
86                 output_row.field_class = idx.field_class;
87                 output_row.field = -1 * idx.id;
88                 output_row.source = rid;
89                 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
90
91                 RETURN NEXT output_row;
92             END IF;
93
94         END LOOP;
95
96         CONTINUE WHEN raw_text IS NULL OR raw_text = '';
97
98         -- insert combined node text for searching
99         IF idx.search_field THEN
100             output_row.field_class = idx.field_class;
101             output_row.field = idx.id;
102             output_row.source = rid;
103             output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
104
105             RETURN NEXT output_row;
106         END IF;
107
108     END LOOP;
109
110 END;
111 $func$ LANGUAGE PLPGSQL;
112
113 COMMIT;