1 --Upgrade Script for 3.8.0 to 3.9.0
2 \set eg_version '''3.9.0'''
4 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.9.0', :eg_version);
6 SELECT evergreen.upgrade_deps_block_check('1307', :eg_version);
8 DROP FUNCTION search.query_parser_fts (
23 DROP TABLE asset.opac_visible_copies;
25 DROP FUNCTION IF EXISTS asset.refresh_opac_visible_copies_mat_view();
27 DROP TYPE search.search_result;
28 DROP TYPE search.search_args;
31 SELECT evergreen.upgrade_deps_block_check('1308', :eg_version);
33 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
35 'eg.grid.admin.local.triggers.atevdef', 'gui', 'object',
37 'eg.grid.admin.local.triggers.atevdef',
38 'Grid Config: eg.grid.admin.local.triggers.atevdef',
42 'eg.grid.admin.local.triggers.atenv', 'gui', 'object',
44 'eg.grid.admin.local.triggers.atenv',
45 'Grid Config: eg.grid.admin.local.triggers.atenv',
49 'eg.grid.admin.local.triggers.atevparam', 'gui', 'object',
51 'eg.grid.admin.local.triggers.atevparam',
52 'Grid Config: eg.grid.admin.local.triggers.atevparam',
58 SELECT evergreen.upgrade_deps_block_check('1309', :eg_version);
60 ALTER TABLE asset.course_module_term
61 DROP CONSTRAINT course_module_term_name_key;
63 ALTER TABLE asset.course_module_term
64 ADD CONSTRAINT cmt_once_per_owning_lib UNIQUE (owning_lib, name);
67 SELECT evergreen.upgrade_deps_block_check('1311', :eg_version);
69 CREATE OR REPLACE FUNCTION biblio.extract_located_uris( bib_id BIGINT, marcxml TEXT, editor_id INT ) RETURNS VOID AS $func$
76 uri_owner_list TEXT[];
85 current_uri_map_list INT[];
86 current_map_owner_list INT[];
90 uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
91 IF ARRAY_UPPER(uris,1) > 0 THEN
92 FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
93 -- First we pull info out of the 856
96 uri_href := (oils_xpath('//*[@code="u"]/text()',uri_xml))[1];
97 uri_label := (oils_xpath('//*[@code="y"]/text()|//*[@code="3"]/text()',uri_xml))[1];
98 uri_use := (oils_xpath('//*[@code="z"]/text()|//*[@code="2"]/text()|//*[@code="n"]/text()',uri_xml))[1];
100 IF uri_label IS NULL THEN
101 uri_label := uri_href;
103 CONTINUE WHEN uri_href IS NULL;
105 -- Get the distinct list of libraries wanting to use
107 DISTINCT REGEXP_REPLACE(
109 $re$^.*?\((\w+)\).*$$re$,
112 ) INTO uri_owner_list
115 '//*[@code="9"]/text()|//*[@code="w"]/text()|//*[@code="n"]/text()',
120 IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
122 -- look for a matching uri
123 IF uri_use IS NULL THEN
124 SELECT id INTO uri_id
126 WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active
128 IF NOT FOUND THEN -- create one
129 INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
130 SELECT id INTO uri_id
132 WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
135 SELECT id INTO uri_id
137 WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active
139 IF NOT FOUND THEN -- create one
140 INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
141 SELECT id INTO uri_id
143 WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
147 FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
148 uri_owner := uri_owner_list[j];
150 SELECT id INTO uri_owner_id FROM actor.org_unit WHERE shortname = BTRIM(REPLACE(uri_owner,chr(160),''));
151 CONTINUE WHEN NOT FOUND;
153 -- we need a call number to link through
154 SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
156 INSERT INTO asset.call_number (owning_lib, record, create_date, edit_date, creator, editor, label)
157 VALUES (uri_owner_id, bib_id, 'now', 'now', editor_id, editor_id, '##URI##');
158 SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
161 -- now, link them if they're not already
162 SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
164 INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
165 SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
168 current_uri_map_list := current_uri_map_list || uri_map_id;
169 current_map_owner_list := current_map_owner_list || uri_cn_id;
178 -- Clear any orphaned URIs, URI mappings and call
179 -- numbers for this bib that weren't mapped above.
182 FROM asset.uri_call_number_map m
183 LEFT JOIN asset.call_number cn ON (cn.id = m.call_number)
184 WHERE cn.record = bib_id
185 AND cn.label = '##URI##'
186 AND (NOT (m.id = ANY (current_uri_map_list))
187 OR current_uri_map_list is NULL)
189 SELECT uri INTO current_uri FROM asset.uri_call_number_map WHERE id = current_map;
190 DELETE FROM asset.uri_call_number_map WHERE id = current_map;
192 SELECT COUNT(*) INTO uri_map_count FROM asset.uri_call_number_map WHERE uri = current_uri;
193 IF uri_map_count = 0 THEN
194 DELETE FROM asset.uri WHERE id = current_uri;
198 UPDATE asset.call_number
199 SET deleted = TRUE, edit_date = now(), editor = editor_id
202 FROM asset.call_number
203 WHERE record = bib_id
204 AND label = '##URI##'
206 AND (NOT (id = ANY (current_map_owner_list))
207 OR current_map_owner_list is NULL)
212 $func$ LANGUAGE PLPGSQL;
214 -- Remove existing orphaned URIs from the database.
215 DELETE FROM asset.uri
220 LEFT JOIN asset.uri_call_number_map
221 ON uri_call_number_map.uri = uri.id
222 LEFT JOIN serial.item
224 WHERE uri_call_number_map IS NULL
230 SELECT evergreen.upgrade_deps_block_check('1312', :eg_version);
232 CREATE INDEX aum_editor ON actor.usr_message (editor);
235 SELECT evergreen.upgrade_deps_block_check('1313', :eg_version); -- alynn26
237 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
239 'eg.grid.cat.bucket.batch_hold.view', 'gui', 'object',
241 'eg.grid.cat.bucket.batch_hold.view',
242 'Grid Config: eg.grid.cat.bucket.batch_hold.view',
246 'eg.grid.cat.bucket.batch_hold.pending', 'gui', 'object',
248 'eg.grid.cat.bucket.batch_hold.pending',
249 'Grid Config: eg.grid.cat.bucket.batch_hold.pending',
253 'eg.grid.cat.bucket.batch_hold.events', 'gui', 'object',
255 'eg.grid.cat.bucket.batch_hold.events',
256 'Grid Config: eg.grid.cat.bucket.batch_hold.events',
260 'eg.grid.cat.bucket.batch_hold.list', 'gui', 'object',
262 'eg.grid.cat.bucket.batch_hold.list',
263 'Grid Config: eg.grid.cat.bucket.batch_hold.list',
269 SELECT evergreen.upgrade_deps_block_check('1314', :eg_version);
271 CREATE OR REPLACE FUNCTION authority.generate_overlay_template (source_xml TEXT) RETURNS TEXT AS $f$
274 main_entry authority.control_set_authority_field%ROWTYPE;
275 bib_field authority.control_set_bib_field%ROWTYPE;
276 auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
278 replace_data XML[] DEFAULT '{}'::XML[];
279 replace_rules TEXT[] DEFAULT '{}'::TEXT[];
284 IF auth_id IS NULL THEN
288 -- Default to the LoC controll set
289 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
291 -- if none, make a best guess
293 SELECT control_set INTO cset
294 FROM authority.control_set_authority_field
296 SELECT UNNEST(XPATH('//*[local-name()="datafield" and starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
297 FROM authority.record_entry
303 -- if STILL none, no-op change
307 XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
308 XMLELEMENT( name leader, '00881nam a2200193 4500'),
311 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
314 XMLATTRIBUTES('d' AS code),
321 FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL LOOP
322 auth_field := XPATH('//*[local-name()="datafield" and @tag="'||main_entry.tag||'"][1]',source_xml::XML);
323 auth_i1 := (XPATH('//*[local-name()="datafield"]/@ind1',auth_field[1]))[1];
324 auth_i2 := (XPATH('//*[local-name()="datafield"]/@ind2',auth_field[1]))[1];
325 IF ARRAY_LENGTH(auth_field,1) > 0 THEN
326 FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP
327 SELECT XMLELEMENT( -- XMLAGG avoids magical <element> creation, but requires unnest subquery
329 XMLATTRIBUTES(bib_field.tag AS tag, auth_i1 AS ind1, auth_i2 AS ind2),
331 ) INTO tmp_data FROM UNNEST(XPATH('//*[local-name()="subfield"]', auth_field[1]));
332 replace_data := replace_data || tmp_data;
333 replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
340 SELECT XMLAGG(UNNEST) INTO tmp_data FROM UNNEST(replace_data);
344 XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
345 XMLELEMENT( name leader, '00881nam a2200193 4500'),
349 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
352 XMLATTRIBUTES('r' AS code),
353 ARRAY_TO_STRING(replace_rules,',')
358 $f$ STABLE LANGUAGE PLPGSQL;
360 CREATE OR REPLACE FUNCTION authority.normalize_heading( marcxml TEXT, no_thesaurus BOOL ) RETURNS TEXT AS $func$
362 acsaf authority.control_set_authority_field%ROWTYPE;
373 auth_id INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
375 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
378 SELECT control_set INTO cset
379 FROM authority.control_set_authority_field
380 WHERE tag IN (SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
385 FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
386 tag_used := acsaf.tag;
387 nfi_used := acsaf.nfi;
390 FOR tag_node IN SELECT unnest(oils_xpath('//*[@tag="'||tag_used||'"]',marcxml))
392 FOR sf_node IN SELECT unnest(oils_xpath('//*[local-name() = "subfield" and contains("'||acsaf.sf_list||'",@code)]',tag_node))
395 tmp_text := oils_xpath_string('.', sf_node);
396 sf := oils_xpath_string('//*/@code', sf_node);
398 IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN
400 tmp_text := SUBSTRING(
405 oils_xpath_string('//*[local-name() = "datafield"]/@ind'||nfi_used, tag_node),
420 IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
421 heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
425 EXIT WHEN heading_text <> '';
428 EXIT WHEN heading_text <> '';
431 IF heading_text <> '' THEN
432 IF no_thesaurus IS TRUE THEN
433 heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
435 thes_code := authority.extract_thesaurus(marcxml);
436 heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
439 heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
444 $func$ LANGUAGE PLPGSQL STABLE STRICT;
446 CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
474 attr_set vandelay.import_item%ROWTYPE;
481 SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
485 attr_set.definition := attr_def.id;
487 -- Build the combined XPath
491 WHEN attr_def.owning_lib IS NULL THEN 'null()'
492 WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@code="' || attr_def.owning_lib || '"]'
493 ELSE '//*' || attr_def.owning_lib
498 WHEN attr_def.circ_lib IS NULL THEN 'null()'
499 WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@code="' || attr_def.circ_lib || '"]'
500 ELSE '//*' || attr_def.circ_lib
505 WHEN attr_def.call_number IS NULL THEN 'null()'
506 WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@code="' || attr_def.call_number || '"]'
507 ELSE '//*' || attr_def.call_number
512 WHEN attr_def.copy_number IS NULL THEN 'null()'
513 WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@code="' || attr_def.copy_number || '"]'
514 ELSE '//*' || attr_def.copy_number
519 WHEN attr_def.status IS NULL THEN 'null()'
520 WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@code="' || attr_def.status || '"]'
521 ELSE '//*' || attr_def.status
526 WHEN attr_def.location IS NULL THEN 'null()'
527 WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@code="' || attr_def.location || '"]'
528 ELSE '//*' || attr_def.location
533 WHEN attr_def.circulate IS NULL THEN 'null()'
534 WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@code="' || attr_def.circulate || '"]'
535 ELSE '//*' || attr_def.circulate
540 WHEN attr_def.deposit IS NULL THEN 'null()'
541 WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@code="' || attr_def.deposit || '"]'
542 ELSE '//*' || attr_def.deposit
547 WHEN attr_def.deposit_amount IS NULL THEN 'null()'
548 WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@code="' || attr_def.deposit_amount || '"]'
549 ELSE '//*' || attr_def.deposit_amount
554 WHEN attr_def.ref IS NULL THEN 'null()'
555 WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@code="' || attr_def.ref || '"]'
556 ELSE '//*' || attr_def.ref
561 WHEN attr_def.holdable IS NULL THEN 'null()'
562 WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@code="' || attr_def.holdable || '"]'
563 ELSE '//*' || attr_def.holdable
568 WHEN attr_def.price IS NULL THEN 'null()'
569 WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@code="' || attr_def.price || '"]'
570 ELSE '//*' || attr_def.price
575 WHEN attr_def.barcode IS NULL THEN 'null()'
576 WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@code="' || attr_def.barcode || '"]'
577 ELSE '//*' || attr_def.barcode
582 WHEN attr_def.circ_modifier IS NULL THEN 'null()'
583 WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@code="' || attr_def.circ_modifier || '"]'
584 ELSE '//*' || attr_def.circ_modifier
589 WHEN attr_def.circ_as_type IS NULL THEN 'null()'
590 WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@code="' || attr_def.circ_as_type || '"]'
591 ELSE '//*' || attr_def.circ_as_type
596 WHEN attr_def.alert_message IS NULL THEN 'null()'
597 WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@code="' || attr_def.alert_message || '"]'
598 ELSE '//*' || attr_def.alert_message
603 WHEN attr_def.opac_visible IS NULL THEN 'null()'
604 WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@code="' || attr_def.opac_visible || '"]'
605 ELSE '//*' || attr_def.opac_visible
610 WHEN attr_def.pub_note IS NULL THEN 'null()'
611 WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@code="' || attr_def.pub_note || '"]'
612 ELSE '//*' || attr_def.pub_note
616 WHEN attr_def.priv_note IS NULL THEN 'null()'
617 WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@code="' || attr_def.priv_note || '"]'
618 ELSE '//*' || attr_def.priv_note
623 WHEN attr_def.internal_id IS NULL THEN 'null()'
624 WHEN LENGTH( attr_def.internal_id ) = 1 THEN '//*[@code="' || attr_def.internal_id || '"]'
625 ELSE '//*' || attr_def.internal_id
630 WHEN attr_def.stat_cat_data IS NULL THEN 'null()'
631 WHEN LENGTH( attr_def.stat_cat_data ) = 1 THEN '//*[@code="' || attr_def.stat_cat_data || '"]'
632 ELSE '//*' || attr_def.stat_cat_data
637 WHEN attr_def.parts_data IS NULL THEN 'null()'
638 WHEN LENGTH( attr_def.parts_data ) = 1 THEN '//*[@code="' || attr_def.parts_data || '"]'
639 ELSE '//*' || attr_def.parts_data
644 xpaths := ARRAY[owning_lib, circ_lib, call_number, copy_number, status, location, circulate,
645 deposit, deposit_amount, ref, holdable, price, barcode, circ_modifier, circ_as_type,
646 alert_message, pub_note, priv_note, internal_id, stat_cat_data, parts_data, opac_visible];
650 FROM oils_xpath_tag_to_table( (SELECT marc FROM vandelay.queued_bib_record WHERE id = import_id), attr_def.tag, xpaths)
651 AS t( ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
652 dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
653 circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT,
654 stat_cat_data TEXT, parts_data TEXT, opac_vis TEXT )
657 attr_set.import_error := NULL;
658 attr_set.error_detail := NULL;
659 attr_set.deposit_amount := NULL;
660 attr_set.copy_number := NULL;
661 attr_set.price := NULL;
662 attr_set.circ_modifier := NULL;
663 attr_set.location := NULL;
664 attr_set.barcode := NULL;
665 attr_set.call_number := NULL;
667 IF tmp_attr_set.pr != '' THEN
668 tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
670 attr_set.import_error := 'import.item.invalid.price';
671 attr_set.error_detail := tmp_attr_set.pr; -- original value
672 RETURN NEXT attr_set; CONTINUE;
674 attr_set.price := tmp_str::NUMERIC(8,2);
677 IF tmp_attr_set.dep_amount != '' THEN
678 tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
680 attr_set.import_error := 'import.item.invalid.deposit_amount';
681 attr_set.error_detail := tmp_attr_set.dep_amount;
682 RETURN NEXT attr_set; CONTINUE;
684 attr_set.deposit_amount := tmp_str::NUMERIC(8,2);
687 IF tmp_attr_set.cnum != '' THEN
688 tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
690 attr_set.import_error := 'import.item.invalid.copy_number';
691 attr_set.error_detail := tmp_attr_set.cnum;
692 RETURN NEXT attr_set; CONTINUE;
694 attr_set.copy_number := tmp_str::INT;
697 IF tmp_attr_set.ol != '' THEN
698 SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
700 attr_set.import_error := 'import.item.invalid.owning_lib';
701 attr_set.error_detail := tmp_attr_set.ol;
702 RETURN NEXT attr_set; CONTINUE;
706 IF tmp_attr_set.clib != '' THEN
707 SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
709 attr_set.import_error := 'import.item.invalid.circ_lib';
710 attr_set.error_detail := tmp_attr_set.clib;
711 RETURN NEXT attr_set; CONTINUE;
715 IF tmp_attr_set.cs != '' THEN
716 SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
718 attr_set.import_error := 'import.item.invalid.status';
719 attr_set.error_detail := tmp_attr_set.cs;
720 RETURN NEXT attr_set; CONTINUE;
724 IF COALESCE(tmp_attr_set.circ_mod, '') = '' THEN
726 -- no circ mod defined, see if we should apply a default
727 SELECT INTO attr_set.circ_modifier TRIM(BOTH '"' FROM value)
728 FROM actor.org_unit_ancestor_setting(
729 'vandelay.item.circ_modifier.default',
733 -- make sure the value from the org setting is still valid
734 PERFORM 1 FROM config.circ_modifier WHERE code = attr_set.circ_modifier;
736 attr_set.import_error := 'import.item.invalid.circ_modifier';
737 attr_set.error_detail := tmp_attr_set.circ_mod;
738 RETURN NEXT attr_set; CONTINUE;
743 SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
745 attr_set.import_error := 'import.item.invalid.circ_modifier';
746 attr_set.error_detail := tmp_attr_set.circ_mod;
747 RETURN NEXT attr_set; CONTINUE;
751 IF tmp_attr_set.circ_as != '' THEN
752 SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
754 attr_set.import_error := 'import.item.invalid.circ_as_type';
755 attr_set.error_detail := tmp_attr_set.circ_as;
756 RETURN NEXT attr_set; CONTINUE;
760 IF COALESCE(tmp_attr_set.cl, '') = '' THEN
761 -- no location specified, see if we should apply a default
763 SELECT INTO attr_set.location TRIM(BOTH '"' FROM value)
764 FROM actor.org_unit_ancestor_setting(
765 'vandelay.item.copy_location.default',
769 -- make sure the value from the org setting is still valid
770 PERFORM 1 FROM asset.copy_location
771 WHERE id = attr_set.location AND NOT deleted;
773 attr_set.import_error := 'import.item.invalid.location';
774 attr_set.error_detail := tmp_attr_set.cs;
775 RETURN NEXT attr_set; CONTINUE;
779 -- search up the org unit tree for a matching copy location
780 WITH RECURSIVE anscestor_depth AS (
784 FROM actor.org_unit ou
785 JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
786 WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
791 FROM actor.org_unit ou
792 JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
793 JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
794 ) SELECT cpl.id INTO attr_set.location
795 FROM anscestor_depth a
796 JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
797 WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl)
799 ORDER BY a.depth DESC
803 attr_set.import_error := 'import.item.invalid.location';
804 attr_set.error_detail := tmp_attr_set.cs;
805 RETURN NEXT attr_set; CONTINUE;
809 attr_set.circulate :=
810 LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
811 OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
814 LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
815 OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
818 LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
819 OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
821 attr_set.opac_visible :=
822 LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
823 OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
826 LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
827 OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
829 attr_set.call_number := tmp_attr_set.cn; -- TEXT
830 attr_set.barcode := tmp_attr_set.bc; -- TEXT,
831 attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
832 attr_set.pub_note := tmp_attr_set.note; -- TEXT,
833 attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
834 attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
835 attr_set.internal_id := tmp_attr_set.internal_id::BIGINT;
836 attr_set.stat_cat_data := tmp_attr_set.stat_cat_data; -- TEXT,
837 attr_set.parts_data := tmp_attr_set.parts_data; -- TEXT,
839 RETURN NEXT attr_set;
850 CREATE OR REPLACE FUNCTION biblio.extract_quality ( marc TEXT, best_lang TEXT, best_type TEXT ) RETURNS INT AS $func$
863 IF marc IS NULL OR marc = '' THEN
867 -- First, the count of tags
868 qual := ARRAY_UPPER(oils_xpath('//*[local-name()="datafield"]', marc), 1);
870 -- now go through a bunch of pain to get the record type
871 IF best_type IS NOT NULL THEN
872 ldr := (oils_xpath('//*[local-name()="leader"]/text()', marc))[1];
874 IF ldr IS NOT NULL THEN
875 SELECT * INTO tval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'Type' LIMIT 1; -- They're all the same
876 SELECT * INTO bval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'BLvl' LIMIT 1; -- They're all the same
879 tval := SUBSTRING( ldr, tval_rec.start_pos + 1, tval_rec.length );
880 bval := SUBSTRING( ldr, bval_rec.start_pos + 1, bval_rec.length );
882 -- RAISE NOTICE 'type %, blvl %, ldr %', tval, bval, ldr;
884 SELECT * INTO type_map FROM config.marc21_rec_type_map WHERE type_val LIKE '%' || tval || '%' AND blvl_val LIKE '%' || bval || '%';
886 IF type_map.code IS NOT NULL THEN
887 IF best_type = type_map.code THEN
888 qual := qual + qual / 2;
891 FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE fixed_field = 'Lang' AND rec_type = type_map.code ORDER BY tag DESC LOOP
892 ff_tag_data := SUBSTRING((oils_xpath('//*[@tag="' || ff_pos.tag || '"]/text()',marc))[1], ff_pos.start_pos + 1, ff_pos.length);
893 IF ff_tag_data = best_lang THEN
901 -- Now look for some quality metrics
903 IF ARRAY_UPPER(oils_xpath('//*[@tag="040"]/*[@code="a" and contains(.,"DLC")]', marc), 1) = 1 THEN
908 IF (oils_xpath('//*[@tag="003"]/text()', marc))[1] ~* E'oclo?c' THEN
915 $func$ LANGUAGE PLPGSQL;
917 CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
919 res authority.simple_heading%ROWTYPE;
920 acsaf authority.control_set_authority_field%ROWTYPE;
921 heading_row authority.heading%ROWTYPE;
932 auth_id INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
935 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
938 SELECT control_set INTO cset
939 FROM authority.control_set_authority_field
940 WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
944 res.record := auth_id;
945 res.thesaurus := authority.extract_thesaurus(marcxml);
947 FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
948 res.atag := acsaf.id;
950 IF acsaf.heading_field IS NULL THEN
951 tag_used := acsaf.tag;
952 nfi_used := acsaf.nfi;
953 joiner_text := COALESCE(acsaf.joiner, ' ');
955 FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)::TEXT[]) LOOP
957 heading_text := COALESCE(
958 oils_xpath_string('//*[local-name()="subfield" and contains("'||acsaf.display_sf_list||'",@code)]', tmp_xml, joiner_text),
962 IF nfi_used IS NOT NULL THEN
964 sort_text := SUBSTRING(
969 oils_xpath_string('//*[local-name()="datafield"]/@ind'||nfi_used, tmp_xml::TEXT),
981 sort_text := heading_text;
984 IF heading_text IS NOT NULL AND heading_text <> '' THEN
985 res.value := heading_text;
986 res.sort_value := public.naco_normalize(sort_text);
987 res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
993 FOR heading_row IN SELECT * FROM authority.extract_headings(marcxml, ARRAY[acsaf.heading_field]) LOOP
994 res.value := heading_row.heading;
995 res.sort_value := heading_row.normalized_heading;
996 res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
1004 $func$ LANGUAGE PLPGSQL STABLE STRICT;
1006 CREATE OR REPLACE FUNCTION metabib.remap_metarecord_for_bib(
1009 bib_is_deleted boolean DEFAULT false,
1010 retain_deleted boolean DEFAULT false
1011 ) RETURNS bigint AS $function$
1013 new_mapping BOOL := TRUE;
1016 tmp_mr metabib.metarecord%ROWTYPE;
1017 deleted_mrs BIGINT[];
1020 -- We need to make sure we're not a deleted master record of an MR
1021 IF bib_is_deleted THEN
1022 IF NOT retain_deleted THEN -- Go away for any MR that we're master of, unless retained
1023 DELETE FROM metabib.metarecord_source_map WHERE source = bib_id;
1026 FOR old_mr IN SELECT id FROM metabib.metarecord WHERE master_record = bib_id LOOP
1028 -- Now, are there any more sources on this MR?
1029 SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = old_mr;
1031 IF source_count = 0 AND NOT retain_deleted THEN -- No other records
1032 deleted_mrs := ARRAY_APPEND(deleted_mrs, old_mr); -- Just in case...
1033 DELETE FROM metabib.metarecord WHERE id = old_mr;
1035 ELSE -- indeed there are. Update it with a null cache and recalcualated master record
1036 UPDATE metabib.metarecord
1038 master_record = (SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC, id ASC LIMIT 1)
1043 ELSE -- insert or update
1045 FOR tmp_mr IN SELECT m.* FROM metabib.metarecord m JOIN metabib.metarecord_source_map s ON (s.metarecord = m.id) WHERE s.source = bib_id LOOP
1047 -- Find the first fingerprint-matching
1048 IF old_mr IS NULL AND fp = tmp_mr.fingerprint THEN
1049 old_mr := tmp_mr.id;
1050 new_mapping := FALSE;
1052 ELSE -- Our fingerprint changed ... maybe remove the old MR
1053 DELETE FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id AND source = bib_id; -- remove the old source mapping
1054 SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id;
1055 IF source_count = 0 THEN -- No other records
1056 deleted_mrs := ARRAY_APPEND(deleted_mrs, tmp_mr.id);
1057 DELETE FROM metabib.metarecord WHERE id = tmp_mr.id;
1063 -- we found no suitable, preexisting MR based on old source maps
1064 IF old_mr IS NULL THEN
1065 SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp; -- is there one for our current fingerprint?
1067 IF old_mr IS NULL THEN -- nope, create one and grab its id
1068 INSERT INTO metabib.metarecord ( fingerprint, master_record ) VALUES ( fp, bib_id );
1069 SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp;
1071 ELSE -- indeed there is. update it with a null cache and recalcualated master record
1072 UPDATE metabib.metarecord
1074 master_record = (SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC, id ASC LIMIT 1)
1078 ELSE -- there was one we already attached to, update its mods cache and master_record
1079 UPDATE metabib.metarecord
1081 master_record = (SELECT id FROM biblio.record_entry WHERE fingerprint = fp AND NOT deleted ORDER BY quality DESC, id ASC LIMIT 1)
1086 INSERT INTO metabib.metarecord_source_map (metarecord, source) VALUES (old_mr, bib_id); -- new source mapping
1091 IF ARRAY_UPPER(deleted_mrs,1) > 0 THEN
1092 UPDATE action.hold_request SET target = old_mr WHERE target IN ( SELECT unnest(deleted_mrs) ) AND hold_type = 'M'; -- if we had to delete any MRs above, make sure their holds are moved
1098 $function$ LANGUAGE plpgsql;
1101 SELECT evergreen.upgrade_deps_block_check('1315', :eg_version);
1103 CREATE TABLE config.ui_staff_portal_page_entry_type (
1104 code TEXT PRIMARY KEY,
1108 INSERT INTO config.ui_staff_portal_page_entry_type (code, label)
1110 ('link', oils_i18n_gettext('link', 'Link', 'cusppet', 'label')),
1111 ('menuitem', oils_i18n_gettext('menuitem', 'Menu Item', 'cusppet', 'label')),
1112 ('text', oils_i18n_gettext('text', 'Text and/or HTML', 'cusppet', 'label')),
1113 ('header', oils_i18n_gettext('header', 'Header', 'cusppet', 'label')),
1114 ('catalogsearch', oils_i18n_gettext('catalogsearch', 'Catalog Search Box', 'cusppet', 'label'));
1117 CREATE TABLE config.ui_staff_portal_page_entry (
1118 id SERIAL PRIMARY KEY,
1119 page_col INTEGER NOT NULL,
1120 col_pos INTEGER NOT NULL,
1121 entry_type TEXT NOT NULL, -- REFERENCES config.ui_staff_portal_page_entry_type(code)
1126 owner INT NOT NULL -- REFERENCES actor.org_unit (id)
1129 ALTER TABLE config.ui_staff_portal_page_entry ADD CONSTRAINT cusppe_entry_type_fkey
1130 FOREIGN KEY (entry_type) REFERENCES config.ui_staff_portal_page_entry_type(code) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
1131 ALTER TABLE config.ui_staff_portal_page_entry ADD CONSTRAINT cusppe_owner_fkey
1132 FOREIGN KEY (owner) REFERENCES actor.org_unit(id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
1135 SELECT evergreen.upgrade_deps_block_check('1316', :eg_version);
1137 INSERT INTO config.ui_staff_portal_page_entry
1138 (id, page_col, col_pos, entry_type, label, image_url, target_url, owner)
1140 ( 1, 1, 0, 'header', oils_i18n_gettext( 1, 'Circulation and Patrons', 'cusppe', 'label'), NULL, NULL, 1)
1141 , ( 2, 1, 1, 'menuitem', oils_i18n_gettext( 2, 'Check Out Items', 'cusppe', 'label'), '/images/portal/forward.png', '/eg/staff/circ/patron/bcsearch', 1)
1142 , ( 3, 1, 2, 'menuitem', oils_i18n_gettext( 3, 'Check In Items', 'cusppe', 'label'), '/images/portal/back.png', '/eg/staff/circ/checkin/index', 1)
1143 , ( 4, 1, 3, 'menuitem', oils_i18n_gettext( 4, 'Search For Patron By Name', 'cusppe', 'label'), '/images/portal/retreivepatron.png', '/eg/staff/circ/patron/search', 1)
1144 , ( 5, 2, 0, 'header', oils_i18n_gettext( 5, 'Item Search and Cataloging', 'cusppe', 'label'), NULL, NULL, 1)
1145 , ( 6, 2, 1, 'catalogsearch', oils_i18n_gettext( 6, 'Search Catalog', 'cusppe', 'label'), NULL, NULL, 1)
1146 , ( 7, 2, 2, 'menuitem', oils_i18n_gettext( 7, 'Record Buckets', 'cusppe', 'label'), '/images/portal/bucket.png', '/eg/staff/cat/bucket/record/', 1)
1147 , ( 8, 2, 3, 'menuitem', oils_i18n_gettext( 8, 'Item Buckets', 'cusppe', 'label'), '/images/portal/bucket.png', '/eg/staff/cat/bucket/copy/', 1)
1148 , ( 9, 3, 0, 'header', oils_i18n_gettext( 9, 'Administration', 'cusppe', 'label'), NULL, NULL, 1)
1149 , (10, 3, 1, 'link', oils_i18n_gettext(10, 'Evergreen Documentation', 'cusppe', 'label'), '/images/portal/helpdesk.png', 'https://docs.evergreen-ils.org', 1)
1150 , (11, 3, 2, 'menuitem', oils_i18n_gettext(11, 'Workstation Administration', 'cusppe', 'label'), '/images/portal/helpdesk.png', '/eg/staff/admin/workstation/index', 1)
1151 , (12, 3, 3, 'menuitem', oils_i18n_gettext(12, 'Reports', 'cusppe', 'label'), '/images/portal/reports.png', '/eg/staff/reporter/legacy/main', 1)
1154 SELECT setval('config.ui_staff_portal_page_entry_id_seq', 100);
1157 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
1159 'eg.grid.admin.config.ui_staff_portal_page_entry', 'gui', 'object',
1161 'eg.grid.admin.config.ui_staff_portal_page_entry',
1162 'Grid Config: admin.config.ui_staff_portal_page_entry',
1169 SELECT evergreen.upgrade_deps_block_check('1317', :eg_version);
1171 INSERT INTO permission.perm_list ( id, code, description ) VALUES
1172 ( 636, 'ADMIN_STAFF_PORTAL_PAGE', oils_i18n_gettext( 636,
1173 'Update the staff client portal page', 'ppl', 'description' ))
1177 -- check whether patch can be applied
1178 SELECT evergreen.upgrade_deps_block_check('1318', :eg_version);
1180 -- 950.data.seed-values.sql
1182 INSERT INTO config.global_flag (name, value, enabled, label)
1184 'opac.cover_upload_compression',
1188 'opac.cover_upload_compression',
1189 'Cover image uploads are converted to PNG files with this compression, on a scale of 0 (no compression) to 9 (maximum compression), or -1 for the zlib default.',
1194 INSERT INTO config.org_unit_setting_type (name, label, grp, description, datatype)
1196 'opac.cover_upload_max_file_size',
1197 oils_i18n_gettext('opac.cover_upload_max_file_size',
1198 'Maximum file size for uploaded cover image files (at time of upload, prior to rescaling).',
1201 oils_i18n_gettext('opac.cover_upload_max_file_size',
1202 'The number of bytes to allow for a cover image upload. If unset, defaults to 10737418240 (roughly 10GB).',
1203 'coust', 'description'),
1207 INSERT INTO permission.perm_list ( id, code, description ) VALUES
1208 ( 637, 'UPLOAD_COVER_IMAGE', oils_i18n_gettext(637,
1209 'Upload local cover images for added content.', 'ppl', 'description'))
1213 SELECT evergreen.upgrade_deps_block_check('1319', :eg_version);
1218 PERFORM TRUE FROM config.usr_setting_type WHERE name = 'cat.copy.templates';
1220 IF NOT FOUND THEN -- no matching user setting
1222 PERFORM TRUE FROM config.workstation_setting_type WHERE name = 'cat.copy.templates';
1225 -- no matching workstation setting
1226 -- Migrate the existing user setting and its data to the new name.
1228 UPDATE config.usr_setting_type
1229 SET name = 'cat.copy.templates'
1230 WHERE name = 'webstaff.cat.copy.templates';
1232 UPDATE actor.usr_setting
1233 SET name = 'cat.copy.templates'
1234 WHERE name = 'webstaff.cat.copy.templates';
1244 SELECT evergreen.upgrade_deps_block_check('1320', :eg_version); -- jboyer / /
1246 ALTER TABLE reporter.template_folder ADD COLUMN simple_reporter BOOLEAN DEFAULT FALSE;
1247 ALTER TABLE reporter.report_folder ADD COLUMN simple_reporter BOOLEAN DEFAULT FALSE;
1248 ALTER TABLE reporter.output_folder ADD COLUMN simple_reporter BOOLEAN DEFAULT FALSE;
1250 DROP INDEX reporter.rpt_template_folder_once_idx;
1251 DROP INDEX reporter.rpt_report_folder_once_idx;
1252 DROP INDEX reporter.rpt_output_folder_once_idx;
1254 CREATE UNIQUE INDEX rpt_template_folder_once_idx ON reporter.template_folder (name,owner,simple_reporter) WHERE parent IS NULL;
1255 CREATE UNIQUE INDEX rpt_report_folder_once_idx ON reporter.report_folder (name,owner,simple_reporter) WHERE parent IS NULL;
1256 CREATE UNIQUE INDEX rpt_output_folder_once_idx ON reporter.output_folder (name,owner,simple_reporter) WHERE parent IS NULL;
1258 -- Private "transform" to allow for simple report permissions verification
1259 CREATE OR REPLACE FUNCTION reporter.intersect_user_perm_ou(context_ou BIGINT, staff_id BIGINT, perm_code TEXT)
1260 RETURNS BOOLEAN AS $$
1261 SELECT CASE WHEN context_ou IN (SELECT * FROM permission.usr_has_perm_at_all(staff_id::INT, perm_code)) THEN TRUE ELSE FALSE END;
1264 -- Hey committer, make sure this id is good to go and also in 950.data.seed-values.sql
1265 INSERT INTO permission.perm_list (id, code, description) VALUES
1266 ( 638, 'RUN_SIMPLE_REPORTS', oils_i18n_gettext(638,
1267 'Build and run simple reports', 'ppl', 'description'));
1270 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
1272 'eg.grid.reporter.simple.reports', 'gui', 'object',
1274 'eg.grid.reporter.simple.reports',
1275 'Grid Config: eg.grid.reporter.simple.reports',
1279 'eg.grid.reporter.simple.outputs', 'gui', 'object',
1281 'eg.grid.reporter.simple.outputs',
1282 'Grid Config: eg.grid.reporter.simple.outputs',
1287 -- new view parallel to reporter.currently_running
1288 -- and reporter.overdue_reports
1289 CREATE OR REPLACE VIEW reporter.completed_reports AS
1293 t.owner AS template_owner,
1294 r.owner AS report_owner,
1296 t.folder AS template_folder,
1297 r.folder AS report_folder,
1298 s.folder AS output_folder,
1299 r.name AS report_name,
1300 t.name AS template_name,
1306 FROM reporter.schedule s
1307 JOIN reporter.report r ON r.id = s.report
1308 JOIN reporter.template t ON t.id = r.template
1309 WHERE s.complete_time IS NOT NULL;
1313 SELECT evergreen.upgrade_deps_block_check('1321', :eg_version);
1315 CREATE TABLE asset.copy_inventory (
1316 id SERIAL PRIMARY KEY,
1317 inventory_workstation INTEGER REFERENCES actor.workstation (id) DEFERRABLE INITIALLY DEFERRED,
1318 inventory_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
1319 copy BIGINT NOT NULL
1321 CREATE INDEX copy_inventory_copy_idx ON asset.copy_inventory (copy);
1322 CREATE UNIQUE INDEX asset_copy_inventory_date_once_per_copy ON asset.copy_inventory (inventory_date, copy);
1324 CREATE OR REPLACE FUNCTION evergreen.asset_copy_inventory_copy_inh_fkey() RETURNS TRIGGER AS $f$
1326 PERFORM 1 FROM asset.copy WHERE id = NEW.copy;
1328 RAISE foreign_key_violation USING MESSAGE = FORMAT(
1329 $$Referenced asset.copy id not found, copy:%s$$, NEW.copy
1334 $f$ LANGUAGE PLPGSQL VOLATILE COST 50;
1336 CREATE CONSTRAINT TRIGGER inherit_asset_copy_inventory_copy_fkey
1337 AFTER UPDATE OR INSERT ON asset.copy_inventory
1338 DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE evergreen.asset_copy_inventory_copy_inh_fkey();
1340 CREATE OR REPLACE FUNCTION asset.copy_may_float_to_inventory_workstation() RETURNS TRIGGER AS $func$
1342 copy asset.copy%ROWTYPE;
1343 workstation actor.workstation%ROWTYPE;
1345 SELECT * INTO copy FROM asset.copy WHERE id = NEW.copy;
1347 SELECT * INTO workstation FROM actor.workstation WHERE id = NEW.inventory_workstation;
1349 IF copy.floating IS NULL THEN
1350 IF copy.circ_lib <> workstation.owning_lib THEN
1351 RAISE EXCEPTION 'Inventory workstation owning lib (%) does not match copy circ lib (%).',
1352 workstation.owning_lib, copy.circ_lib;
1355 IF NOT evergreen.can_float(copy.floating, copy.circ_lib, workstation.owning_lib) THEN
1356 RAISE EXCEPTION 'Copy (%) cannot float to inventory workstation owning lib (%).',
1357 copy.id, workstation.owning_lib;
1364 $func$ LANGUAGE PLPGSQL VOLATILE COST 50;
1366 CREATE CONSTRAINT TRIGGER asset_copy_inventory_allowed_trig
1367 AFTER UPDATE OR INSERT ON asset.copy_inventory
1368 DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE asset.copy_may_float_to_inventory_workstation();
1370 INSERT INTO asset.copy_inventory
1371 (inventory_workstation, inventory_date, copy)
1372 SELECT DISTINCT ON (inventory_date, copy) inventory_workstation, inventory_date, copy
1373 FROM asset.latest_inventory
1374 JOIN asset.copy acp ON acp.id = latest_inventory.copy
1375 JOIN actor.workstation ON workstation.id = latest_inventory.inventory_workstation
1376 WHERE acp.circ_lib = workstation.owning_lib
1378 SELECT DISTINCT ON (inventory_date, copy) inventory_workstation, inventory_date, copy
1379 FROM asset.latest_inventory
1380 JOIN asset.copy acp ON acp.id = latest_inventory.copy
1381 JOIN actor.workstation ON workstation.id = latest_inventory.inventory_workstation
1382 WHERE acp.circ_lib <> workstation.owning_lib
1383 AND acp.floating IS NOT NULL
1384 AND evergreen.can_float(acp.floating, acp.circ_lib, workstation.owning_lib)
1385 ORDER by inventory_date;
1387 DROP TABLE asset.latest_inventory;
1389 CREATE VIEW asset.latest_inventory (id, inventory_workstation, inventory_date, copy) AS
1390 SELECT DISTINCT ON (copy) id, inventory_workstation, inventory_date, copy
1391 FROM asset.copy_inventory
1392 ORDER BY copy, inventory_date DESC;
1394 DROP FUNCTION evergreen.asset_latest_inventory_copy_inh_fkey();
1397 SELECT evergreen.upgrade_deps_block_check('1322', :eg_version);
1399 INSERT into config.org_unit_setting_type
1400 ( name, grp, label, description, datatype, fm_class ) VALUES
1401 ( 'opac.patron.custom_jquery', 'opac',
1402 oils_i18n_gettext('opac.patron.custom_jquery',
1403 'Custom jQuery for the OPAC',
1405 oils_i18n_gettext('opac.patron.custom_jquery',
1406 'Custom jQuery for the OPAC',
1407 'coust', 'description'),
1411 SELECT evergreen.upgrade_deps_block_check('1323', :eg_version);
1413 -- VIEWS for the oai service
1416 -- The view presents a lean table with unique bre.tc-numbers for oai paging;
1417 CREATE VIEW oai.biblio AS
1420 bre.edit_date AT TIME ZONE 'UTC' AS datestamp,
1421 bre.deleted AS deleted
1423 biblio.record_entry bre
1427 -- The view presents a lean table with unique are.tc-numbers for oai paging;
1428 CREATE VIEW oai.authority AS
1431 are.edit_date AT TIME ZONE 'UTC' AS datestamp,
1432 are.deleted AS deleted
1434 authority.record_entry AS are
1438 CREATE OR REPLACE function oai.bib_is_visible_at_org_by_copy(bib BIGINT, org INT) RETURNS BOOL AS $F$
1439 WITH corgs AS (SELECT array_agg(id) AS list FROM actor.org_unit_descendants(org))
1440 SELECT EXISTS (SELECT 1 FROM asset.copy_vis_attr_cache, corgs WHERE vis_attr_vector @@ search.calculate_visibility_attribute_test('circ_lib', corgs.list)::query_int AND bib=record)
1441 $F$ LANGUAGE SQL STABLE;
1443 CREATE OR REPLACE function oai.bib_is_visible_at_org_by_luri(bib BIGINT, org INT) RETURNS BOOL AS $F$
1444 WITH lorgs AS(SELECT array_agg(id) AS list FROM actor.org_unit_ancestors(org))
1445 SELECT EXISTS (SELECT 1 FROM biblio.record_entry, lorgs WHERE vis_attr_vector @@ search.calculate_visibility_attribute_test('luri_org', lorgs.list)::query_int AND bib=id)
1446 $F$ LANGUAGE SQL STABLE;
1448 CREATE OR REPLACE function oai.bib_is_visible_by_source(bib BIGINT, src TEXT) RETURNS BOOL AS $F$
1449 SELECT EXISTS (SELECT 1 FROM biblio.record_entry b JOIN config.bib_source s ON (b.source = s.id) WHERE transcendant AND s.source = src AND bib=b.id)
1450 $F$ LANGUAGE SQL STABLE;
1452 CREATE OR REPLACE function oai.auth_is_visible_by_axis(auth BIGINT, ax TEXT) RETURNS BOOL AS $F$
1453 SELECT EXISTS (SELECT 1 FROM authority.browse_axis_authority_field_map m JOIN authority.simple_heading r on (r.atag = m.field AND r.record = auth AND m.axis = ax))
1454 $F$ LANGUAGE SQL STABLE;
1458 SELECT evergreen.upgrade_deps_block_check('1324', :eg_version);
1460 CREATE TABLE action_trigger.alternate_template (
1462 event_def INTEGER REFERENCES action_trigger.event_definition(id) INITIALLY DEFERRED,
1464 active BOOLEAN DEFAULT TRUE,
1466 message_template TEXT,
1467 locale TEXT REFERENCES config.i18n_locale(code) INITIALLY DEFERRED,
1468 UNIQUE (event_def,locale)
1471 ALTER TABLE actor.usr ADD COLUMN locale TEXT REFERENCES config.i18n_locale(code) INITIALLY DEFERRED;
1473 ALTER TABLE action_trigger.event_output ADD COLUMN locale TEXT;
1476 SELECT evergreen.upgrade_deps_block_check('1325', :eg_version);
1478 UPDATE config.xml_transform SET xslt=$XSLT$<?xml version="1.0" encoding="UTF-8"?>
1479 <xsl:stylesheet version="1.0" xmlns:mads="http://www.loc.gov/mads/v2"
1480 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim"
1481 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
1482 <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
1483 <xsl:strip-space elements="*"/>
1485 <xsl:variable name="ascii">
1486 <xsl:text> !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
1489 <xsl:variable name="latin1">
1490 <xsl:text> ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
1492 <!-- Characters that usually don't need to be escaped -->
1493 <xsl:variable name="safe">
1494 <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
1497 <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
1500 <xsl:template name="datafield">
1501 <xsl:param name="tag"/>
1502 <xsl:param name="ind1">
1503 <xsl:text> </xsl:text>
1505 <xsl:param name="ind2">
1506 <xsl:text> </xsl:text>
1508 <xsl:param name="subfields"/>
1509 <xsl:element name="marc:datafield">
1510 <xsl:attribute name="tag">
1511 <xsl:value-of select="$tag"/>
1513 <xsl:attribute name="ind1">
1514 <xsl:value-of select="$ind1"/>
1516 <xsl:attribute name="ind2">
1517 <xsl:value-of select="$ind2"/>
1519 <xsl:copy-of select="$subfields"/>
1523 <xsl:template name="subfieldSelect">
1524 <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
1525 <xsl:param name="delimeter">
1526 <xsl:text> </xsl:text>
1528 <xsl:variable name="str">
1529 <xsl:for-each select="marc:subfield">
1530 <xsl:if test="contains($codes, @code)">
1531 <xsl:value-of select="text()"/>
1532 <xsl:value-of select="$delimeter"/>
1536 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
1539 <xsl:template name="buildSpaces">
1540 <xsl:param name="spaces"/>
1541 <xsl:param name="char">
1542 <xsl:text> </xsl:text>
1544 <xsl:if test="$spaces>0">
1545 <xsl:value-of select="$char"/>
1546 <xsl:call-template name="buildSpaces">
1547 <xsl:with-param name="spaces" select="$spaces - 1"/>
1548 <xsl:with-param name="char" select="$char"/>
1549 </xsl:call-template>
1553 <xsl:template name="chopPunctuation">
1554 <xsl:param name="chopString"/>
1555 <xsl:param name="punctuation">
1556 <xsl:text>.:,;/ </xsl:text>
1558 <xsl:variable name="length" select="string-length($chopString)"/>
1560 <xsl:when test="$length=0"/>
1561 <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
1562 <xsl:call-template name="chopPunctuation">
1563 <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
1564 <xsl:with-param name="punctuation" select="$punctuation"/>
1565 </xsl:call-template>
1567 <xsl:when test="not($chopString)"/>
1569 <xsl:value-of select="$chopString"/>
1574 <xsl:template name="chopPunctuationFront">
1575 <xsl:param name="chopString"/>
1576 <xsl:variable name="length" select="string-length($chopString)"/>
1578 <xsl:when test="$length=0"/>
1579 <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
1580 <xsl:call-template name="chopPunctuationFront">
1581 <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
1583 </xsl:call-template>
1585 <xsl:when test="not($chopString)"/>
1587 <xsl:value-of select="$chopString"/>
1592 <xsl:template name="chopPunctuationBack">
1593 <xsl:param name="chopString"/>
1594 <xsl:param name="punctuation">
1595 <xsl:text>.:,;/] </xsl:text>
1597 <xsl:variable name="length" select="string-length($chopString)"/>
1599 <xsl:when test="$length=0"/>
1600 <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
1601 <xsl:call-template name="chopPunctuation">
1602 <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
1603 <xsl:with-param name="punctuation" select="$punctuation"/>
1604 </xsl:call-template>
1606 <xsl:when test="not($chopString)"/>
1608 <xsl:value-of select="$chopString"/>
1613 <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
1614 <xsl:template name="url-encode">
1616 <xsl:param name="str"/>
1618 <xsl:if test="$str">
1619 <xsl:variable name="first-char" select="substring($str,1,1)"/>
1621 <xsl:when test="contains($safe,$first-char)">
1622 <xsl:value-of select="$first-char"/>
1625 <xsl:variable name="codepoint">
1627 <xsl:when test="contains($ascii,$first-char)">
1629 select="string-length(substring-before($ascii,$first-char)) + 32"
1632 <xsl:when test="contains($latin1,$first-char)">
1634 select="string-length(substring-before($latin1,$first-char)) + 160"/>
1638 <xsl:message terminate="no">Warning: string contains a character
1639 that is out of range! Substituting "?".</xsl:message>
1640 <xsl:text>63</xsl:text>
1644 <xsl:variable name="hex-digit1"
1645 select="substring($hex,floor($codepoint div 16) + 1,1)"/>
1646 <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
1647 <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
1648 <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
1651 <xsl:if test="string-length($str) > 1">
1652 <xsl:call-template name="url-encode">
1653 <xsl:with-param name="str" select="substring($str,2)"/>
1654 </xsl:call-template>
1661 2.15 reversed genre and setAuthority template order under relatedTypeAttribute tmee 11/13/2018
1662 2.14 Fixed bug in mads:geographic attributes syntax ws 05/04/2016
1663 2.13 fixed repeating <geographic> tmee 01/31/2014
1664 2.12 added $2 authority for <classification> tmee 09/18/2012
1665 2.11 added delimiters between <classification> subfields tmee 09/18/2012
1666 2.10 fixed type="other" and type="otherType" for mads:related tmee 09/16/2011
1667 2.09 fixed professionTerm and genreTerm empty tag error tmee 09/16/2011
1668 2.08 fixed marc:subfield @code='i' matching error tmee 09/16/2011
1669 2.07 fixed 555 duplication error tmee 08/10/2011
1670 2.06 fixed topic subfield error tmee 08/10/2011
1671 2.05 fixed title subfield error tmee 06/20/2011
1672 2.04 fixed geographicSubdivision mapping for authority element tmee 06/16/2011
1673 2.03 added classification for 053, 055, 060, 065, 070, 080, 082, 083, 086, 087 tmee 06/03/2011
1674 2.02 added descriptionStandard for 008/10 tmee 04/27/2011
1675 2.01 added extensions for 046, 336, 370, 374, 375, 376 tmee 04/08/2011
1676 2.00 redefined imported MODS elements in version 1.0 to MADS elements in version 2.0 tmee 02/08/2011
1677 1.08 added 372 subfields $a $s $t for <fieldOfActivity> tmee 06/24/2010
1678 1.07 removed role/roleTerm 100, 110, 111, 400, 410, 411, 500, 510, 511, 700, 710, 711 tmee 06/24/2010
1679 1.06 added strip-space tmee 06/24/2010
1680 1.05 added subfield $a for 130, 430, 530 tmee 06/21/2010
1681 1.04 fixed 550 z omission ntra 08/11/2008
1682 1.03 removed duplication of 550 $a text tmee 11/01/2006
1683 1.02 fixed namespace references between mads and mods ntra 10/06/2006
1684 1.01 revised rgue/jrad 11/29/05
1685 1.00 adapted from MARC21Slim2MODS3.xsl ntra 07/06/05
1688 <!-- authority attribute defaults to 'naf' if not set using this authority parameter, for <authority> descriptors: name, titleInfo, geographic -->
1689 <xsl:param name="authority"/>
1690 <xsl:variable name="auth">
1692 <xsl:when test="$authority">
1693 <xsl:value-of select="$authority"/>
1695 <xsl:otherwise>naf</xsl:otherwise>
1698 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
1699 <xsl:variable name="controlField008-06"
1700 select="substring(descendant-or-self::marc:controlfield[@tag=008],7,1)"/>
1701 <xsl:variable name="controlField008-11"
1702 select="substring(descendant-or-self::marc:controlfield[@tag=008],12,1)"/>
1703 <xsl:variable name="controlField008-14"
1704 select="substring(descendant-or-self::marc:controlfield[@tag=008],15,1)"/>
1705 <xsl:template match="/">
1707 <xsl:when test="descendant-or-self::marc:collection">
1708 <mads:madsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1709 xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/v2/mads-2-0.xsd">
1710 <xsl:for-each select="descendant-or-self::marc:collection/marc:record">
1711 <mads:mads version="2.0">
1712 <xsl:call-template name="marcRecord"/>
1715 </mads:madsCollection>
1718 <mads:mads version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1719 xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/mads-2-0.xsd">
1720 <xsl:for-each select="descendant-or-self::marc:record">
1721 <xsl:call-template name="marcRecord"/>
1728 <xsl:template name="marcRecord">
1732 <xsl:when test="$controlField008-06='d'">
1733 <xsl:attribute name="geographicSubdivision">
1734 <xsl:text>direct</xsl:text>
1737 <xsl:when test="$controlField008-06='i'">
1738 <xsl:attribute name="geographicSubdivision">
1739 <xsl:text>indirect</xsl:text>
1742 <xsl:when test="$controlField008-06='n'">
1743 <xsl:attribute name="geographicSubdivision">
1744 <xsl:text>not applicable</xsl:text>
1749 <xsl:apply-templates select="marc:datafield[100 <= @tag and @tag < 200]"/>
1753 <xsl:apply-templates
1754 select="marc:datafield[500 <= @tag and @tag <= 585]|marc:datafield[700 <= @tag and @tag <= 785]"/>
1757 <xsl:apply-templates select="marc:datafield[400 <= @tag and @tag <= 485]"/>
1760 <xsl:apply-templates select="marc:datafield[667 <= @tag and @tag <= 688]"/>
1763 <xsl:apply-templates select="marc:datafield[@tag=856]"/>
1764 <xsl:apply-templates select="marc:datafield[@tag=010]"/>
1765 <xsl:apply-templates select="marc:datafield[@tag=024]"/>
1766 <xsl:apply-templates select="marc:datafield[@tag=372]"/>
1768 <!-- classification -->
1769 <xsl:apply-templates select="marc:datafield[@tag=053]"/>
1770 <xsl:apply-templates select="marc:datafield[@tag=055]"/>
1771 <xsl:apply-templates select="marc:datafield[@tag=060]"/>
1772 <xsl:apply-templates select="marc:datafield[@tag=065]"/>
1773 <xsl:apply-templates select="marc:datafield[@tag=070]"/>
1774 <xsl:apply-templates select="marc:datafield[@tag=080]"/>
1775 <xsl:apply-templates select="marc:datafield[@tag=082]"/>
1776 <xsl:apply-templates select="marc:datafield[@tag=083]"/>
1777 <xsl:apply-templates select="marc:datafield[@tag=086]"/>
1778 <xsl:apply-templates select="marc:datafield[@tag=087]"/>
1781 <xsl:for-each select="marc:datafield[@tag=373]">
1784 <xsl:value-of select="marc:subfield[@code='a']"/>
1786 <mads:dateValid point="start">
1787 <xsl:value-of select="marc:subfield[@code='s']"/>
1789 <mads:dateValid point="end">
1790 <xsl:value-of select="marc:subfield[@code='t']"/>
1794 <xsl:for-each select="marc:datafield[@tag=371]">
1798 <xsl:value-of select="marc:subfield[@code='a']"/>
1801 <xsl:value-of select="marc:subfield[@code='b']"/>
1804 <xsl:value-of select="marc:subfield[@code='c']"/>
1807 <xsl:value-of select="marc:subfield[@code='d']"/>
1810 <xsl:value-of select="marc:subfield[@code='e']"/>
1814 <xsl:value-of select="marc:subfield[@code='m']"/>
1820 <xsl:for-each select="marc:datafield[@tag=336]">
1823 <mads:contentType type="text">
1824 <xsl:value-of select="marc:subfield[@code='a']"/>
1826 <mads:contentType type="code">
1827 <xsl:value-of select="marc:subfield[@code='b']"/>
1833 <xsl:for-each select="marc:datafield[@tag=374]">
1837 <xsl:when test="marc:subfield[@code='a']">
1838 <mads:professionTerm>
1839 <xsl:value-of select="marc:subfield[@code='a']"/>
1840 </mads:professionTerm>
1842 <xsl:when test="marc:subfield[@code='s']">
1843 <mads:dateValid point="start">
1844 <xsl:value-of select="marc:subfield[@code='s']"/>
1847 <xsl:when test="marc:subfield[@code='t']">
1848 <mads:dateValid point="end">
1849 <xsl:value-of select="marc:subfield[@code='t']"/>
1857 <xsl:for-each select="marc:datafield[@tag=375]">
1861 <xsl:when test="marc:subfield[@code='a']">
1863 <xsl:value-of select="marc:subfield[@code='a']"/>
1866 <xsl:when test="marc:subfield[@code='s']">
1867 <mads:dateValid point="start">
1868 <xsl:value-of select="marc:subfield[@code='s']"/>
1871 <xsl:when test="marc:subfield[@code='t']">
1872 <mads:dateValid point="end">
1873 <xsl:value-of select="marc:subfield[@code='t']"/>
1881 <xsl:for-each select="marc:datafield[@tag=376]">
1883 <mads:familyInformation>
1885 <xsl:value-of select="marc:subfield[@code='a']"/>
1886 </mads:typeOfFamily>
1887 <mads:nameOfProminentMember>
1888 <xsl:value-of select="marc:subfield[@code='b']"/>
1889 </mads:nameOfProminentMember>
1890 <mads:hereditaryTitle>
1891 <xsl:value-of select="marc:subfield[@code='c']"/>
1892 </mads:hereditaryTitle>
1893 <mads:dateValid point="start">
1894 <xsl:value-of select="marc:subfield[@code='s']"/>
1896 <mads:dateValid point="end">
1897 <xsl:value-of select="marc:subfield[@code='t']"/>
1899 </mads:familyInformation>
1904 <mads:recordOrigin>Converted from MARCXML to MADS version 2.0 (Revision 2.13)</mads:recordOrigin>
1905 <!-- <xsl:apply-templates select="marc:datafield[@tag=024]"/> -->
1907 <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='a']"/>
1908 <xsl:apply-templates select="marc:controlfield[@tag=005]"/>
1909 <xsl:apply-templates select="marc:controlfield[@tag=001]"/>
1910 <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='b']"/>
1911 <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='e']"/>
1912 <xsl:for-each select="marc:controlfield[@tag=008]">
1913 <xsl:if test="substring(.,11,1)='a'">
1914 <mads:descriptionStandard>
1915 <xsl:text>earlier rules</xsl:text>
1916 </mads:descriptionStandard>
1918 <xsl:if test="substring(.,11,1)='b'">
1919 <mads:descriptionStandard>
1920 <xsl:text>aacr1</xsl:text>
1921 </mads:descriptionStandard>
1923 <xsl:if test="substring(.,11,1)='c'">
1924 <mads:descriptionStandard>
1925 <xsl:text>aacr2</xsl:text>
1926 </mads:descriptionStandard>
1928 <xsl:if test="substring(.,11,1)='d'">
1929 <mads:descriptionStandard>
1930 <xsl:text>aacr2 compatible</xsl:text>
1931 </mads:descriptionStandard>
1933 <xsl:if test="substring(.,11,1)='z'">
1934 <mads:descriptionStandard>
1935 <xsl:text>other rules</xsl:text>
1936 </mads:descriptionStandard>
1942 <!-- start of secondary templates -->
1944 <!-- ======== xlink ======== -->
1946 <!-- <xsl:template name="uri">
1947 <xsl:for-each select="marc:subfield[@code='0']">
1948 <xsl:attribute name="xlink:href">
1949 <xsl:value-of select="."/>
1954 <xsl:template match="marc:subfield[@code='i']">
1955 <xsl:attribute name="otherType">
1956 <xsl:value-of select="."/>
1960 <!-- No role/roleTerm mapped in MADS 06/24/2010
1961 <xsl:template name="role">
1962 <xsl:for-each select="marc:subfield[@code='e']">
1964 <mads:roleTerm type="text">
1965 <xsl:value-of select="."/>
1972 <xsl:template name="part">
1973 <xsl:variable name="partNumber">
1974 <xsl:call-template name="specialSubfieldSelect">
1975 <xsl:with-param name="axis">n</xsl:with-param>
1976 <xsl:with-param name="anyCodes">n</xsl:with-param>
1977 <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
1978 </xsl:call-template>
1980 <xsl:variable name="partName">
1981 <xsl:call-template name="specialSubfieldSelect">
1982 <xsl:with-param name="axis">p</xsl:with-param>
1983 <xsl:with-param name="anyCodes">p</xsl:with-param>
1984 <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
1985 </xsl:call-template>
1987 <xsl:if test="string-length(normalize-space($partNumber))">
1989 <xsl:call-template name="chopPunctuation">
1990 <xsl:with-param name="chopString" select="$partNumber"/>
1991 </xsl:call-template>
1994 <xsl:if test="string-length(normalize-space($partName))">
1996 <xsl:call-template name="chopPunctuation">
1997 <xsl:with-param name="chopString" select="$partName"/>
1998 </xsl:call-template>
2003 <xsl:template name="nameABCDN">
2004 <xsl:for-each select="marc:subfield[@code='a']">
2006 <xsl:call-template name="chopPunctuation">
2007 <xsl:with-param name="chopString" select="."/>
2008 </xsl:call-template>
2011 <xsl:for-each select="marc:subfield[@code='b']">
2013 <xsl:value-of select="."/>
2017 test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
2019 <xsl:call-template name="subfieldSelect">
2020 <xsl:with-param name="codes">cdn</xsl:with-param>
2021 </xsl:call-template>
2026 <xsl:template name="nameABCDQ">
2028 <xsl:call-template name="chopPunctuation">
2029 <xsl:with-param name="chopString">
2030 <xsl:call-template name="subfieldSelect">
2031 <xsl:with-param name="codes">aq</xsl:with-param>
2032 </xsl:call-template>
2034 </xsl:call-template>
2036 <xsl:call-template name="termsOfAddress"/>
2037 <xsl:call-template name="nameDate"/>
2040 <xsl:template name="nameACDENQ">
2042 <xsl:call-template name="subfieldSelect">
2043 <xsl:with-param name="codes">acdenq</xsl:with-param>
2044 </xsl:call-template>
2048 <xsl:template name="nameDate">
2049 <xsl:for-each select="marc:subfield[@code='d']">
2050 <mads:namePart type="date">
2051 <xsl:call-template name="chopPunctuation">
2052 <xsl:with-param name="chopString" select="."/>
2053 </xsl:call-template>
2058 <xsl:template name="specialSubfieldSelect">
2059 <xsl:param name="anyCodes"/>
2060 <xsl:param name="axis"/>
2061 <xsl:param name="beforeCodes"/>
2062 <xsl:param name="afterCodes"/>
2063 <xsl:variable name="str">
2064 <xsl:for-each select="marc:subfield">
2066 test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
2067 <xsl:value-of select="text()"/>
2068 <xsl:text> </xsl:text>
2072 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
2075 <xsl:template name="termsOfAddress">
2076 <xsl:if test="marc:subfield[@code='b' or @code='c']">
2077 <mads:namePart type="termsOfAddress">
2078 <xsl:call-template name="chopPunctuation">
2079 <xsl:with-param name="chopString">
2080 <xsl:call-template name="subfieldSelect">
2081 <xsl:with-param name="codes">bc</xsl:with-param>
2082 </xsl:call-template>
2084 </xsl:call-template>
2089 <xsl:template name="displayLabel">
2090 <xsl:if test="marc:subfield[@code='z']">
2091 <xsl:attribute name="displayLabel">
2092 <xsl:value-of select="marc:subfield[@code='z']"/>
2095 <xsl:if test="marc:subfield[@code='3']">
2096 <xsl:attribute name="displayLabel">
2097 <xsl:value-of select="marc:subfield[@code='3']"/>
2102 <xsl:template name="isInvalid">
2103 <xsl:if test="@code='z'">
2104 <xsl:attribute name="invalid">yes</xsl:attribute>
2108 <xsl:template name="sub2Attribute">
2110 <xsl:if test="../marc:subfield[@code='2']">
2111 <xsl:attribute name="type">
2112 <xsl:value-of select="../marc:subfield[@code='2']"/>
2117 <xsl:template match="marc:controlfield[@tag=001]">
2118 <mads:recordIdentifier>
2119 <xsl:if test="../marc:controlfield[@tag=003]">
2120 <xsl:attribute name="source">
2121 <xsl:value-of select="../marc:controlfield[@tag=003]"/>
2124 <xsl:value-of select="."/>
2125 </mads:recordIdentifier>
2128 <xsl:template match="marc:controlfield[@tag=005]">
2129 <mads:recordChangeDate encoding="iso8601">
2130 <xsl:value-of select="."/>
2131 </mads:recordChangeDate>
2134 <xsl:template match="marc:controlfield[@tag=008]">
2135 <mads:recordCreationDate encoding="marc">
2136 <xsl:value-of select="substring(.,1,6)"/>
2137 </mads:recordCreationDate>
2140 <xsl:template match="marc:datafield[@tag=010]">
2141 <xsl:for-each select="marc:subfield">
2142 <mads:identifier type="lccn">
2143 <xsl:call-template name="isInvalid"/>
2144 <xsl:value-of select="."/>
2149 <xsl:template match="marc:datafield[@tag=024]">
2150 <xsl:for-each select="marc:subfield[not(@code=2)]">
2152 <xsl:call-template name="isInvalid"/>
2153 <xsl:call-template name="sub2Attribute"/>
2154 <xsl:value-of select="."/>
2159 <!-- ========== 372 ========== -->
2160 <xsl:template match="marc:datafield[@tag=372]">
2161 <mads:fieldOfActivity>
2162 <xsl:call-template name="subfieldSelect">
2163 <xsl:with-param name="codes">a</xsl:with-param>
2164 </xsl:call-template>
2165 <xsl:text>-</xsl:text>
2166 <xsl:call-template name="subfieldSelect">
2167 <xsl:with-param name="codes">st</xsl:with-param>
2168 </xsl:call-template>
2169 </mads:fieldOfActivity>
2173 <!-- ========== 040 ========== -->
2174 <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='a']">
2175 <mads:recordContentSource authority="marcorg">
2176 <xsl:value-of select="."/>
2177 </mads:recordContentSource>
2180 <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='b']">
2181 <mads:languageOfCataloging>
2182 <mads:languageTerm authority="iso639-2b" type="code">
2183 <xsl:value-of select="."/>
2184 </mads:languageTerm>
2185 </mads:languageOfCataloging>
2188 <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='e']">
2189 <mads:descriptionStandard>
2190 <xsl:value-of select="."/>
2191 </mads:descriptionStandard>
2194 <!-- ========== classification 2.03 ========== -->
2196 <xsl:template match="marc:datafield[@tag=053]">
2197 <mads:classification>
2198 <xsl:call-template name="subfieldSelect">
2199 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
2200 <xsl:with-param name="delimeter">-</xsl:with-param>
2201 </xsl:call-template>
2202 </mads:classification>
2205 <xsl:template match="marc:datafield[@tag=055]">
2206 <mads:classification>
2207 <xsl:call-template name="subfieldSelect">
2208 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
2209 <xsl:with-param name="delimeter">-</xsl:with-param>
2210 </xsl:call-template>
2211 </mads:classification>
2214 <xsl:template match="marc:datafield[@tag=060]">
2215 <mads:classification>
2216 <xsl:call-template name="subfieldSelect">
2217 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
2218 <xsl:with-param name="delimeter">-</xsl:with-param>
2219 </xsl:call-template>
2220 </mads:classification>
2222 <xsl:template match="marc:datafield[@tag=065]">
2223 <mads:classification>
2224 <xsl:attribute name="authority">
2225 <xsl:value-of select="marc:subfield[@code='2']"/>
2227 <xsl:call-template name="subfieldSelect">
2228 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
2229 <xsl:with-param name="delimeter">-</xsl:with-param>
2230 </xsl:call-template>
2231 </mads:classification>
2233 <xsl:template match="marc:datafield[@tag=070]">
2234 <mads:classification>
2235 <xsl:call-template name="subfieldSelect">
2236 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
2237 <xsl:with-param name="delimeter">-</xsl:with-param>
2238 </xsl:call-template>
2239 </mads:classification>
2241 <xsl:template match="marc:datafield[@tag=080]">
2242 <mads:classification>
2243 <xsl:attribute name="authority">
2244 <xsl:value-of select="marc:subfield[@code='2']"/>
2246 <xsl:call-template name="subfieldSelect">
2247 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
2248 <xsl:with-param name="delimeter">-</xsl:with-param>
2249 </xsl:call-template>
2250 </mads:classification>
2252 <xsl:template match="marc:datafield[@tag=082]">
2253 <mads:classification>
2254 <xsl:attribute name="authority">
2255 <xsl:value-of select="marc:subfield[@code='2']"/>
2257 <xsl:call-template name="subfieldSelect">
2258 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
2259 <xsl:with-param name="delimeter">-</xsl:with-param>
2260 </xsl:call-template>
2261 </mads:classification>
2263 <xsl:template match="marc:datafield[@tag=083]">
2264 <mads:classification>
2265 <xsl:attribute name="authority">
2266 <xsl:value-of select="marc:subfield[@code='2']"/>
2268 <xsl:call-template name="subfieldSelect">
2269 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
2270 <xsl:with-param name="delimeter">-</xsl:with-param>
2271 </xsl:call-template>
2272 </mads:classification>
2274 <xsl:template match="marc:datafield[@tag=086]">
2275 <mads:classification>
2276 <xsl:attribute name="authority">
2277 <xsl:value-of select="marc:subfield[@code='2']"/>
2279 <xsl:call-template name="subfieldSelect">
2280 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
2281 <xsl:with-param name="delimeter">-</xsl:with-param>
2282 </xsl:call-template>
2283 </mads:classification>
2285 <xsl:template match="marc:datafield[@tag=087]">
2286 <mads:classification>
2287 <xsl:attribute name="authority">
2288 <xsl:value-of select="marc:subfield[@code='2']"/>
2290 <xsl:call-template name="subfieldSelect">
2291 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
2292 <xsl:with-param name="delimeter">-</xsl:with-param>
2293 </xsl:call-template>
2294 </mads:classification>
2298 <!-- ========== names ========== -->
2299 <xsl:template match="marc:datafield[@tag=100]">
2300 <mads:name type="personal">
2301 <xsl:call-template name="setAuthority"/>
2302 <xsl:call-template name="nameABCDQ"/>
2304 <xsl:apply-templates select="*[marc:subfield[not(contains('abcdeq',@code))]]"/>
2305 <xsl:call-template name="title"/>
2306 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2309 <xsl:template match="marc:datafield[@tag=110]">
2310 <mads:name type="corporate">
2311 <xsl:call-template name="setAuthority"/>
2312 <xsl:call-template name="nameABCDN"/>
2314 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2317 <xsl:template match="marc:datafield[@tag=111]">
2318 <mads:name type="conference">
2319 <xsl:call-template name="setAuthority"/>
2320 <xsl:call-template name="nameACDENQ"/>
2322 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2325 <xsl:template match="marc:datafield[@tag=400]">
2327 <xsl:call-template name="variantTypeAttribute"/>
2328 <mads:name type="personal">
2329 <xsl:call-template name="nameABCDQ"/>
2331 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2332 <xsl:call-template name="title"/>
2336 <xsl:template match="marc:datafield[@tag=410]">
2338 <xsl:call-template name="variantTypeAttribute"/>
2339 <mads:name type="corporate">
2340 <xsl:call-template name="nameABCDN"/>
2342 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2346 <xsl:template match="marc:datafield[@tag=411]">
2348 <xsl:call-template name="variantTypeAttribute"/>
2349 <mads:name type="conference">
2350 <xsl:call-template name="nameACDENQ"/>
2352 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2356 <xsl:template match="marc:datafield[@tag=500]|marc:datafield[@tag=700]">
2358 <xsl:call-template name="relatedTypeAttribute"/>
2359 <!-- <xsl:call-template name="uri"/> -->
2360 <mads:name type="personal">
2361 <xsl:call-template name="setAuthority"/>
2362 <xsl:call-template name="nameABCDQ"/>
2364 <xsl:call-template name="title"/>
2365 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2369 <xsl:template match="marc:datafield[@tag=510]|marc:datafield[@tag=710]">
2371 <xsl:call-template name="relatedTypeAttribute"/>
2372 <!-- <xsl:call-template name="uri"/> -->
2373 <mads:name type="corporate">
2374 <xsl:call-template name="setAuthority"/>
2375 <xsl:call-template name="nameABCDN"/>
2377 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2381 <xsl:template match="marc:datafield[@tag=511]|marc:datafield[@tag=711]">
2383 <xsl:call-template name="relatedTypeAttribute"/>
2384 <!-- <xsl:call-template name="uri"/> -->
2385 <mads:name type="conference">
2386 <xsl:call-template name="setAuthority"/>
2387 <xsl:call-template name="nameACDENQ"/>
2389 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2393 <!-- ========== titles ========== -->
2394 <xsl:template match="marc:datafield[@tag=130]">
2395 <xsl:call-template name="uniform-title"/>
2396 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2399 <xsl:template match="marc:datafield[@tag=430]">
2401 <xsl:call-template name="variantTypeAttribute"/>
2402 <xsl:call-template name="uniform-title"/>
2403 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2407 <xsl:template match="marc:datafield[@tag=530]|marc:datafield[@tag=730]">
2409 <xsl:call-template name="relatedTypeAttribute"/>
2410 <xsl:call-template name="uniform-title"/>
2411 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2415 <xsl:template name="title">
2416 <xsl:variable name="hasTitle">
2417 <xsl:for-each select="marc:subfield">
2418 <xsl:if test="(contains('tfghklmors',@code) )">
2419 <xsl:value-of select="@code"/>
2423 <xsl:if test="string-length($hasTitle) > 0 ">
2425 <xsl:call-template name="setAuthority"/>
2427 <xsl:variable name="str">
2428 <xsl:for-each select="marc:subfield">
2429 <xsl:if test="(contains('atfghklmors',@code) )">
2430 <xsl:value-of select="text()"/>
2431 <xsl:text> </xsl:text>
2435 <xsl:call-template name="chopPunctuation">
2436 <xsl:with-param name="chopString">
2437 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
2439 </xsl:call-template>
2441 <xsl:call-template name="part"/>
2442 <!-- <xsl:call-template name="uri"/> -->
2447 <xsl:template name="uniform-title">
2448 <xsl:variable name="hasTitle">
2449 <xsl:for-each select="marc:subfield">
2450 <xsl:if test="(contains('atfghklmors',@code) )">
2451 <xsl:value-of select="@code"/>
2455 <xsl:if test="string-length($hasTitle) > 0 ">
2457 <xsl:call-template name="setAuthority"/>
2459 <xsl:variable name="str">
2460 <xsl:for-each select="marc:subfield">
2461 <xsl:if test="(contains('adfghklmors',@code) )">
2462 <xsl:value-of select="text()"/>
2463 <xsl:text> </xsl:text>
2467 <xsl:call-template name="chopPunctuation">
2468 <xsl:with-param name="chopString">
2469 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
2471 </xsl:call-template>
2473 <xsl:call-template name="part"/>
2474 <!-- <xsl:call-template name="uri"/> -->
2480 <!-- ========== topics ========== -->
2481 <xsl:template match="marc:subfield[@code='x']">
2483 <xsl:call-template name="chopPunctuation">
2484 <xsl:with-param name="chopString">
2485 <xsl:value-of select="."/>
2487 </xsl:call-template>
2493 match="marc:datafield[@tag=150][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=180][marc:subfield[@code='x']]">
2494 <xsl:call-template name="topic"/>
2495 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2498 match="marc:datafield[@tag=450][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=480][marc:subfield[@code='x']]">
2500 <xsl:call-template name="variantTypeAttribute"/>
2501 <xsl:call-template name="topic"/>
2505 match="marc:datafield[@tag=550 or @tag=750][marc:subfield[@code='a' or @code='b']]">
2507 <xsl:call-template name="relatedTypeAttribute"/>
2508 <!-- <xsl:call-template name="uri"/> -->
2509 <xsl:call-template name="topic"/>
2510 <xsl:apply-templates select="marc:subfield[@code='z']"/>
2513 <xsl:template name="topic">
2515 <xsl:call-template name="setAuthority"/>
2516 <!-- tmee2006 dedupe 550a
2517 <xsl:if test="@tag=550 or @tag=750">
2518 <xsl:call-template name="subfieldSelect">
2519 <xsl:with-param name="codes">ab</xsl:with-param>
2520 </xsl:call-template>
2524 <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
2525 <xsl:call-template name="chopPunctuation">
2526 <xsl:with-param name="chopString">
2527 <xsl:apply-templates select="marc:subfield[@code='x']"/>
2529 </xsl:call-template>
2532 <xsl:call-template name="chopPunctuation">
2533 <xsl:with-param name="chopString">
2535 <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
2536 <xsl:apply-templates select="marc:subfield[@code='x']"/>
2539 <xsl:call-template name="subfieldSelect">
2540 <xsl:with-param name="codes">ab</xsl:with-param>
2541 </xsl:call-template>
2545 </xsl:call-template>
2549 <!-- ========= temporals ========== -->
2550 <xsl:template match="marc:subfield[@code='y']">
2552 <xsl:call-template name="chopPunctuation">
2553 <xsl:with-param name="chopString">
2554 <xsl:value-of select="."/>
2556 </xsl:call-template>
2560 match="marc:datafield[@tag=148][marc:subfield[@code='a']]|marc:datafield[@tag=182 ][marc:subfield[@code='y']]">
2561 <xsl:call-template name="temporal"/>
2564 match="marc:datafield[@tag=448][marc:subfield[@code='a']]|marc:datafield[@tag=482][marc:subfield[@code='y']]">
2566 <xsl:call-template name="variantTypeAttribute"/>
2567 <xsl:call-template name="temporal"/>
2571 match="marc:datafield[@tag=548 or @tag=748][marc:subfield[@code='a']]|marc:datafield[@tag=582 or @tag=782][marc:subfield[@code='y']]">
2573 <xsl:call-template name="relatedTypeAttribute"/>
2574 <!-- <xsl:call-template name="uri"/> -->
2575 <xsl:call-template name="temporal"/>
2578 <xsl:template name="temporal">
2580 <xsl:call-template name="setAuthority"/>
2581 <xsl:if test="@tag=548 or @tag=748">
2582 <xsl:value-of select="marc:subfield[@code='a']"/>
2584 <xsl:call-template name="chopPunctuation">
2585 <xsl:with-param name="chopString">
2587 <xsl:when test="@tag=182 or @tag=482 or @tag=582 or @tag=782">
2588 <xsl:apply-templates select="marc:subfield[@code='y']"/>
2591 <xsl:value-of select="marc:subfield[@code='a']"/>
2595 </xsl:call-template>
2597 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2600 <!-- ========== genre ========== -->
2601 <xsl:template match="marc:subfield[@code='v']">
2603 <xsl:call-template name="chopPunctuation">
2604 <xsl:with-param name="chopString">
2605 <xsl:value-of select="."/>
2607 </xsl:call-template>
2611 match="marc:datafield[@tag=155][marc:subfield[@code='a']]|marc:datafield[@tag=185][marc:subfield[@code='v']]">
2612 <xsl:call-template name="genre"/>
2615 match="marc:datafield[@tag=455][marc:subfield[@code='a']]|marc:datafield[@tag=485 ][marc:subfield[@code='v']]">
2617 <xsl:call-template name="variantTypeAttribute"/>
2618 <xsl:call-template name="genre"/>
2622 <xsl:template match="marc:datafield[@tag=555]">
2624 <xsl:call-template name="relatedTypeAttribute"/>
2625 <xsl:call-template name="uri"/>
2626 <xsl:call-template name="genre"/>
2631 match="marc:datafield[@tag=555 or @tag=755][marc:subfield[@code='a']]|marc:datafield[@tag=585][marc:subfield[@code='v']]">
2633 <xsl:call-template name="relatedTypeAttribute"/>
2634 <xsl:call-template name="genre"/>
2637 <xsl:template name="genre">
2639 <xsl:if test="@tag=555">
2640 <xsl:value-of select="marc:subfield[@code='a']"/>
2642 <xsl:call-template name="setAuthority"/>
2643 <xsl:call-template name="chopPunctuation">
2644 <xsl:with-param name="chopString">
2647 <xsl:when test="@tag='555'"/>
2648 <xsl:when test="@tag=185 or @tag=485 or @tag=585">
2649 <xsl:apply-templates select="marc:subfield[@code='v']"/>
2652 <xsl:value-of select="marc:subfield[@code='a']"/>
2656 </xsl:call-template>
2658 <xsl:apply-templates/>
2661 <!-- ========= geographic ========== -->
2662 <xsl:template match="marc:subfield[@code='z']">
2664 <xsl:call-template name="chopPunctuation">
2665 <xsl:with-param name="chopString">
2666 <xsl:value-of select="."/>
2668 </xsl:call-template>
2671 <xsl:template name="geographic">
2674 <xsl:call-template name="setAuthority"/>
2676 <xsl:if test="@tag=151 or @tag=551">
2677 <xsl:value-of select="marc:subfield[@code='a']"/>
2679 <xsl:call-template name="chopPunctuation">
2680 <xsl:with-param name="chopString">
2681 <xsl:if test="@tag=181 or @tag=481 or @tag=581">
2682 <xsl:apply-templates select="marc:subfield[@code='z']"/>
2686 <xsl:when test="@tag=181 or @tag=481 or @tag=581">
2687 <xsl:apply-templates select="marc:subfield[@code='z']"/>
2691 <xsl:value-of select="marc:subfield[@code='a']"/>
2696 </xsl:call-template>
2698 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2701 match="marc:datafield[@tag=151][marc:subfield[@code='a']]|marc:datafield[@tag=181][marc:subfield[@code='z']]">
2702 <xsl:call-template name="geographic"/>
2705 match="marc:datafield[@tag=451][marc:subfield[@code='a']]|marc:datafield[@tag=481][marc:subfield[@code='z']]">
2707 <xsl:call-template name="variantTypeAttribute"/>
2708 <xsl:call-template name="geographic"/>
2712 match="marc:datafield[@tag=551]|marc:datafield[@tag=581][marc:subfield[@code='z']]">
2714 <xsl:call-template name="relatedTypeAttribute"/>
2715 <!-- <xsl:call-template name="uri"/> -->
2716 <xsl:call-template name="geographic"/>
2719 <xsl:template match="marc:datafield[@tag=580]">
2721 <xsl:call-template name="relatedTypeAttribute"/>
2722 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2726 match="marc:datafield[@tag=751][marc:subfield[@code='z']]|marc:datafield[@tag=781][marc:subfield[@code='z']]">
2728 <xsl:call-template name="relatedTypeAttribute"/>
2729 <xsl:call-template name="geographic"/>
2732 <xsl:template match="marc:datafield[@tag=755]">
2734 <xsl:call-template name="relatedTypeAttribute"/>
2735 <xsl:call-template name="setAuthority"/>
2736 <xsl:call-template name="genre"/>
2737 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2740 <xsl:template match="marc:datafield[@tag=780]">
2742 <xsl:call-template name="relatedTypeAttribute"/>
2743 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2746 <xsl:template match="marc:datafield[@tag=785]">
2748 <xsl:call-template name="relatedTypeAttribute"/>
2749 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
2753 <!-- ========== notes ========== -->
2754 <xsl:template match="marc:datafield[667 <= @tag and @tag <= 688]">
2757 <xsl:when test="@tag=667">
2758 <xsl:attribute name="type">nonpublic</xsl:attribute>
2760 <xsl:when test="@tag=670">
2761 <xsl:attribute name="type">source</xsl:attribute>
2763 <xsl:when test="@tag=675">
2764 <xsl:attribute name="type">notFound</xsl:attribute>
2766 <xsl:when test="@tag=678">
2767 <xsl:attribute name="type">history</xsl:attribute>
2769 <xsl:when test="@tag=681">
2770 <xsl:attribute name="type">subject example</xsl:attribute>
2772 <xsl:when test="@tag=682">
2773 <xsl:attribute name="type">deleted heading information</xsl:attribute>
2775 <xsl:when test="@tag=688">
2776 <xsl:attribute name="type">application history</xsl:attribute>
2779 <xsl:call-template name="chopPunctuation">
2780 <xsl:with-param name="chopString">
2782 <xsl:when test="@tag=667 or @tag=675">
2783 <xsl:value-of select="marc:subfield[@code='a']"/>
2785 <xsl:when test="@tag=670 or @tag=678">
2786 <xsl:call-template name="subfieldSelect">
2787 <xsl:with-param name="codes">ab</xsl:with-param>
2788 </xsl:call-template>
2790 <xsl:when test="680 <= @tag and @tag <=688">
2791 <xsl:call-template name="subfieldSelect">
2792 <xsl:with-param name="codes">ai</xsl:with-param>
2793 </xsl:call-template>
2797 </xsl:call-template>
2801 <!-- ========== url ========== -->
2802 <xsl:template match="marc:datafield[@tag=856][marc:subfield[@code='u']]">
2804 <xsl:if test="marc:subfield[@code='z' or @code='3']">
2805 <xsl:attribute name="displayLabel">
2806 <xsl:call-template name="subfieldSelect">
2807 <xsl:with-param name="codes">z3</xsl:with-param>
2808 </xsl:call-template>
2811 <xsl:value-of select="marc:subfield[@code='u']"/>
2815 <xsl:template name="relatedTypeAttribute">
2818 test="@tag=500 or @tag=510 or @tag=511 or @tag=548 or @tag=550 or @tag=551 or @tag=555 or @tag=580 or @tag=581 or @tag=582 or @tag=585">
2819 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='a'">
2820 <xsl:attribute name="type">earlier</xsl:attribute>
2822 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='b'">
2823 <xsl:attribute name="type">later</xsl:attribute>
2825 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='t'">
2826 <xsl:attribute name="type">parentOrg</xsl:attribute>
2828 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='g'">
2829 <xsl:attribute name="type">broader</xsl:attribute>
2831 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='h'">
2832 <xsl:attribute name="type">narrower</xsl:attribute>
2834 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='r'">
2835 <xsl:attribute name="type">other</xsl:attribute>
2837 <xsl:if test="contains('fin|', substring(marc:subfield[@code='w'],1,1))">
2838 <xsl:attribute name="type">other</xsl:attribute>
2841 <xsl:when test="@tag=530 or @tag=730">
2842 <xsl:attribute name="type">other</xsl:attribute>
2846 <xsl:attribute name="type">equivalent</xsl:attribute>
2849 <xsl:apply-templates select="marc:subfield[@code='i']"/>
2854 <xsl:template name="variantTypeAttribute">
2857 test="@tag=400 or @tag=410 or @tag=411 or @tag=451 or @tag=455 or @tag=480 or @tag=481 or @tag=482 or @tag=485">
2858 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='d'">
2859 <xsl:attribute name="type">acronym</xsl:attribute>
2861 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='n'">
2862 <xsl:attribute name="type">other</xsl:attribute>
2864 <xsl:if test="contains('fit', substring(marc:subfield[@code='w'],1,1))">
2865 <xsl:attribute name="type">other</xsl:attribute>
2870 <xsl:attribute name="type">other</xsl:attribute>
2873 <xsl:apply-templates select="marc:subfield[@code='i']"/>
2876 <xsl:template name="setAuthority">
2878 <!-- can be called from the datafield or subfield level, so "..//@tag" means
2879 the tag can be at the subfield's parent level or at the datafields own level -->
2882 test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='a'">
2883 <xsl:attribute name="authority">
2884 <xsl:text>naf</xsl:text>
2888 test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='b'">
2889 <xsl:attribute name="authority">
2890 <xsl:text>lcsh</xsl:text>
2894 test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='k'">
2895 <xsl:attribute name="authority">
2896 <xsl:text>lacnaf</xsl:text>
2900 test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='a' and $controlField008-14='b'">
2901 <xsl:attribute name="authority">
2902 <xsl:text>lcsh</xsl:text>
2906 test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='k' and $controlField008-14='b'">
2907 <xsl:attribute name="authority">cash</xsl:attribute>
2910 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='a'">
2911 <xsl:attribute name="authority">naf</xsl:attribute>
2914 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='b'">
2915 <xsl:attribute name="authority">lcsh</xsl:attribute>
2918 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='a'">
2919 <xsl:attribute name="authority">
2920 <xsl:text>lacnaf</xsl:text>
2924 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='b'">
2925 <xsl:attribute name="authority">
2926 <xsl:text>cash</xsl:text>
2930 test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='b'">
2931 <xsl:attribute name="authority">
2932 <xsl:text>lcshcl</xsl:text>
2936 test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='c'">
2937 <xsl:attribute name="authority">
2938 <xsl:text>nlmnaf</xsl:text>
2942 test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='d'">
2943 <xsl:attribute name="authority">
2944 <xsl:text>nalnaf</xsl:text>
2948 test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='r'">
2949 <xsl:attribute name="authority">
2950 <xsl:text>aat</xsl:text>
2954 test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='s'">
2955 <xsl:attribute name="authority">sears</xsl:attribute>
2958 test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='v'">
2959 <xsl:attribute name="authority">rvm</xsl:attribute>
2962 test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='z'">
2963 <xsl:attribute name="authority">
2965 select="../marc:datafield[ancestor-or-self::marc:datafield/@tag=040]/marc:subfield[@code='f']"
2970 test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='a'">
2971 <xsl:attribute name="authority">
2972 <xsl:text>naf</xsl:text>
2976 test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='b'">
2977 <xsl:attribute name="authority">
2978 <xsl:text>lcsh</xsl:text>
2982 test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='k' ">
2983 <xsl:attribute name="authority">
2984 <xsl:text>lacnaf</xsl:text>
2988 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
2989 <xsl:attribute name="authority">
2990 <xsl:text>lcsh</xsl:text>
2994 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
2995 <xsl:attribute name="authority">
2996 <xsl:text>lcsh</xsl:text>
3000 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='c' ">
3001 <xsl:attribute name="authority">
3002 <xsl:text>mesh</xsl:text>
3006 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='d' ">
3007 <xsl:attribute name="authority">
3008 <xsl:text>nal</xsl:text>
3012 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='k' ">
3013 <xsl:attribute name="authority">
3014 <xsl:text>cash</xsl:text>
3018 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='a'">
3019 <xsl:attribute name="authority">
3020 <xsl:text>naf</xsl:text>
3024 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='b'">
3025 <xsl:attribute name="authority">lcsh</xsl:attribute>
3028 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='a'">
3029 <xsl:attribute name="authority">lacnaf</xsl:attribute>
3032 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='b'">
3033 <xsl:attribute name="authority">cash</xsl:attribute>
3036 test="(..//ancestor-or-self::marc:datafield/@tag=180 or ..//ancestor-or-self::marc:datafield/@tag=181 or ..//ancestor-or-self::marc:datafield/@tag=182 or ..//ancestor-or-self::marc:datafield/@tag=185) and $controlField008-11='a'">
3037 <xsl:attribute name="authority">lcsh</xsl:attribute>
3040 test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='0'">
3041 <xsl:attribute name="authority">naf</xsl:attribute>
3044 test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='5'">
3045 <xsl:attribute name="authority">lacnaf</xsl:attribute>
3047 <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='0'">
3048 <xsl:attribute name="authority">lcsh</xsl:attribute>
3050 <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='5'">
3051 <xsl:attribute name="authority">cash</xsl:attribute>
3054 test="(700 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 755 ) and @ind2='1'">
3055 <xsl:attribute name="authority">lcshcl</xsl:attribute>
3058 test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='2'">
3059 <xsl:attribute name="authority">nlmnaf</xsl:attribute>
3062 test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='3'">
3063 <xsl:attribute name="authority">nalnaf</xsl:attribute>
3066 test="(700 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 755 ) and @ind2='6'">
3067 <xsl:attribute name="authority">rvm</xsl:attribute>
3070 test="(700 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 755 ) and @ind2='7'">
3071 <xsl:attribute name="authority">
3072 <xsl:value-of select="marc:subfield[@code='2']"/>
3076 test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='5'">
3077 <xsl:attribute name="authority">lacnaf</xsl:attribute>
3080 test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='0'">
3081 <xsl:attribute name="authority">naf</xsl:attribute>
3084 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='0'">
3085 <xsl:attribute name="authority">lcsh</xsl:attribute>
3088 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='2'">
3089 <xsl:attribute name="authority">mesh</xsl:attribute>
3092 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='3'">
3093 <xsl:attribute name="authority">nal</xsl:attribute>
3096 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='5'">
3097 <xsl:attribute name="authority">cash</xsl:attribute>
3101 <xsl:template match="*"/>
3102 </xsl:stylesheet>$XSLT$ WHERE name = 'mads21';
3105 SELECT evergreen.upgrade_deps_block_check('1310', :eg_version);
3107 DROP AGGREGATE IF EXISTS array_accum(anyelement) CASCADE;
3112 -- Update auditor tables to catch changes to source tables.
3113 -- Can be removed/skipped if there were no schema changes.
3114 SELECT auditor.update_auditors();