]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0750.function.authority.generate_overlay_template.sql
LP#1772955: Only include xacts with balance in summary
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0750.function.authority.generate_overlay_template.sql
1 -- Only consider main entry headings for bib overlay
2
3 BEGIN;
4
5 -- check whether patch can be applied
6 SELECT evergreen.upgrade_deps_block_check('0750', :eg_version);
7
8
9 -- Function to generate an ephemeral overlay template from an authority record
10 CREATE OR REPLACE FUNCTION authority.generate_overlay_template (source_xml TEXT) RETURNS TEXT AS $f$
11 DECLARE
12     cset                INT;
13     main_entry          authority.control_set_authority_field%ROWTYPE;
14     bib_field           authority.control_set_bib_field%ROWTYPE;
15     auth_id             INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
16     replace_data        XML[] DEFAULT '{}'::XML[];
17     replace_rules       TEXT[] DEFAULT '{}'::TEXT[];
18     auth_field          XML[];
19 BEGIN
20     IF auth_id IS NULL THEN
21         RETURN NULL;
22     END IF;
23
24     -- Default to the LoC controll set
25     SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
26
27     -- if none, make a best guess
28     IF cset IS NULL THEN
29         SELECT  control_set INTO cset
30           FROM  authority.control_set_authority_field
31           WHERE tag IN (
32                     SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
33                       FROM  authority.record_entry
34                       WHERE id = auth_id
35                 )
36           LIMIT 1;
37     END IF;
38
39     -- if STILL none, no-op change
40     IF cset IS NULL THEN
41         RETURN XMLELEMENT(
42             name record,
43             XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
44             XMLELEMENT( name leader, '00881nam a2200193   4500'),
45             XMLELEMENT(
46                 name datafield,
47                 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
48                 XMLELEMENT(
49                     name subfield,
50                     XMLATTRIBUTES('d' AS code),
51                     '901c'
52                 )
53             )
54         )::TEXT;
55     END IF;
56
57     FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL LOOP
58         auth_field := XPATH('//*[@tag="'||main_entry.tag||'"][1]',source_xml::XML);
59         IF ARRAY_LENGTH(auth_field,1) > 0 THEN
60             FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP
61                 replace_data := replace_data || XMLELEMENT( name datafield, XMLATTRIBUTES(bib_field.tag AS tag), XPATH('//*[local-name()="subfield"]',auth_field[1])::XML[]);
62                 replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
63             END LOOP;
64             EXIT;
65         END IF;
66     END LOOP;
67
68     RETURN XMLELEMENT(
69         name record,
70         XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
71         XMLELEMENT( name leader, '00881nam a2200193   4500'),
72         replace_data,
73         XMLELEMENT(
74             name datafield,
75             XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
76             XMLELEMENT(
77                 name subfield,
78                 XMLATTRIBUTES('r' AS code),
79                 ARRAY_TO_STRING(replace_rules,',')
80             )
81         )
82     )::TEXT;
83 END;
84 $f$ STABLE LANGUAGE PLPGSQL;
85
86 -- Change the two argument form of vandelay.merge_record_xml to
87 -- prevent bibliographic record destruction when there is nothing to
88 -- do.
89
90
91 CREATE OR REPLACE FUNCTION vandelay.merge_record_xml ( target_marc TEXT, template_marc TEXT ) RETURNS TEXT AS $$
92 DECLARE
93     dyn_profile     vandelay.compile_profile%ROWTYPE;
94     replace_rule    TEXT;
95     tmp_marc        TEXT;
96     trgt_marc        TEXT;
97     tmpl_marc        TEXT;
98     match_count     INT;
99 BEGIN
100
101     IF target_marc IS NULL OR template_marc IS NULL THEN
102         -- RAISE NOTICE 'no marc for target or template record';
103         RETURN NULL;
104     END IF;
105
106     dyn_profile := vandelay.compile_profile( template_marc );
107
108     IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN
109         -- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule;
110         RETURN NULL;
111     END IF;
112
113     IF dyn_profile.replace_rule = '' AND dyn_profile.preserve_rule = '' AND dyn_profile.add_rule = '' THEN
114         --Since we have nothing to do, just return what we were given.
115         RETURN target_marc;
116     ELSIF dyn_profile.replace_rule <> '' THEN
117         trgt_marc = target_marc;
118         tmpl_marc = template_marc;
119         replace_rule = dyn_profile.replace_rule;
120     ELSE
121         tmp_marc = target_marc;
122         trgt_marc = template_marc;
123         tmpl_marc = tmp_marc;
124         replace_rule = dyn_profile.preserve_rule;
125     END IF;
126
127     RETURN vandelay.merge_record_xml( trgt_marc, tmpl_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule );
128
129 END;
130 $$ LANGUAGE PLPGSQL;
131
132 CREATE OR REPLACE FUNCTION vandelay.template_overlay_bib_record ( v_marc TEXT, eg_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$
133 DECLARE
134     merge_profile   vandelay.merge_profile%ROWTYPE;
135     dyn_profile     vandelay.compile_profile%ROWTYPE;
136     editor_string   TEXT;
137     editor_id       INT;
138     source_marc     TEXT;
139     target_marc     TEXT;
140     eg_marc         TEXT;
141     replace_rule    TEXT;
142     match_count     INT;
143 BEGIN
144
145     SELECT  b.marc INTO eg_marc
146       FROM  biblio.record_entry b
147       WHERE b.id = eg_id
148       LIMIT 1;
149
150     IF eg_marc IS NULL OR v_marc IS NULL THEN
151         -- RAISE NOTICE 'no marc for template or bib record';
152         RETURN FALSE;
153     END IF;
154
155     dyn_profile := vandelay.compile_profile( v_marc );
156
157     IF merge_profile_id IS NOT NULL THEN
158         SELECT * INTO merge_profile FROM vandelay.merge_profile WHERE id = merge_profile_id;
159         IF FOUND THEN
160             dyn_profile.add_rule := BTRIM( dyn_profile.add_rule || ',' || COALESCE(merge_profile.add_spec,''), ',');
161             dyn_profile.strip_rule := BTRIM( dyn_profile.strip_rule || ',' || COALESCE(merge_profile.strip_spec,''), ',');
162             dyn_profile.replace_rule := BTRIM( dyn_profile.replace_rule || ',' || COALESCE(merge_profile.replace_spec,''), ',');
163             dyn_profile.preserve_rule := BTRIM( dyn_profile.preserve_rule || ',' || COALESCE(merge_profile.preserve_spec,''), ',');
164         END IF;
165     END IF;
166
167     IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN
168         -- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule;
169         RETURN FALSE;
170     END IF;
171
172     IF dyn_profile.replace_rule = '' AND dyn_profile.preserve_rule = '' AND dyn_profile.add_rule = '' AND dyn_profile.strip_rule = '' THEN
173         --Since we have nothing to do, just return a NOOP "we did it"
174         RETURN TRUE;
175     ELSIF dyn_profile.replace_rule <> '' THEN
176         source_marc = v_marc;
177         target_marc = eg_marc;
178         replace_rule = dyn_profile.replace_rule;
179     ELSE
180         source_marc = eg_marc;
181         target_marc = v_marc;
182         replace_rule = dyn_profile.preserve_rule;
183     END IF;
184
185     UPDATE  biblio.record_entry
186       SET   marc = vandelay.merge_record_xml( target_marc, source_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule )
187       WHERE id = eg_id;
188
189     IF NOT FOUND THEN
190         -- RAISE NOTICE 'update of biblio.record_entry failed';
191         RETURN FALSE;
192     END IF;
193
194     RETURN TRUE;
195
196 END;
197 $$ LANGUAGE PLPGSQL;
198
199 CREATE OR REPLACE FUNCTION vandelay.overlay_authority_record ( import_id BIGINT, eg_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$
200 DECLARE
201     merge_profile   vandelay.merge_profile%ROWTYPE;
202     dyn_profile     vandelay.compile_profile%ROWTYPE;
203     source_marc     TEXT;
204     target_marc     TEXT;
205     eg_marc         TEXT;
206     v_marc          TEXT;
207     replace_rule    TEXT;
208     match_count     INT;
209 BEGIN
210
211     SELECT  b.marc INTO eg_marc
212       FROM  authority.record_entry b
213             JOIN vandelay.authority_match m ON (m.eg_record = b.id AND m.queued_record = import_id)
214       LIMIT 1;
215
216     SELECT  q.marc INTO v_marc
217       FROM  vandelay.queued_record q
218             JOIN vandelay.authority_match m ON (m.queued_record = q.id AND q.id = import_id)
219       LIMIT 1;
220
221     IF eg_marc IS NULL OR v_marc IS NULL THEN
222         -- RAISE NOTICE 'no marc for vandelay or authority record';
223         RETURN FALSE;
224     END IF;
225
226     dyn_profile := vandelay.compile_profile( v_marc );
227
228     IF merge_profile_id IS NOT NULL THEN
229         SELECT * INTO merge_profile FROM vandelay.merge_profile WHERE id = merge_profile_id;
230         IF FOUND THEN
231             dyn_profile.add_rule := BTRIM( dyn_profile.add_rule || ',' || COALESCE(merge_profile.add_spec,''), ',');
232             dyn_profile.strip_rule := BTRIM( dyn_profile.strip_rule || ',' || COALESCE(merge_profile.strip_spec,''), ',');
233             dyn_profile.replace_rule := BTRIM( dyn_profile.replace_rule || ',' || COALESCE(merge_profile.replace_spec,''), ',');
234             dyn_profile.preserve_rule := BTRIM( dyn_profile.preserve_rule || ',' || COALESCE(merge_profile.preserve_spec,''), ',');
235         END IF;
236     END IF;
237
238     IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN
239         -- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule;
240         RETURN FALSE;
241     END IF;
242
243     IF dyn_profile.replace_rule = '' AND dyn_profile.preserve_rule = '' AND dyn_profile.add_rule = '' AND dyn_profile.strip_rule = '' THEN
244         --Since we have nothing to do, just return a NOOP "we did it"
245         RETURN TRUE;
246     ELSIF dyn_profile.replace_rule <> '' THEN
247         source_marc = v_marc;
248         target_marc = eg_marc;
249         replace_rule = dyn_profile.replace_rule;
250     ELSE
251         source_marc = eg_marc;
252         target_marc = v_marc;
253         replace_rule = dyn_profile.preserve_rule;
254     END IF;
255
256     UPDATE  authority.record_entry
257       SET   marc = vandelay.merge_record_xml( target_marc, source_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule )
258       WHERE id = eg_id;
259
260     IF FOUND THEN
261         UPDATE  vandelay.queued_authority_record
262           SET   imported_as = eg_id,
263                 import_time = NOW()
264           WHERE id = import_id;
265         RETURN TRUE;
266     END IF;
267
268     -- RAISE NOTICE 'update of authority.record_entry failed';
269
270     RETURN FALSE;
271
272 END;
273 $$ LANGUAGE PLPGSQL;
274
275 COMMIT;