From: Bill Erickson Date: Fri, 17 Jan 2014 19:36:36 +0000 (-0500) Subject: LP#1053397 initial unapi.mmr() support X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=4570a9a692b789b2e0f0a9d108c6fe5a3c175563;p=working%2FEvergreen.git LP#1053397 initial unapi.mmr() support Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.unapi-mmr.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.unapi-mmr.sql new file mode 100644 index 0000000000..cdcef16886 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.unapi-mmr.sql @@ -0,0 +1,171 @@ +BEGIN; + +/* +using unapi.bre_output_layout for now. +Do we need separate output config for mmr? +*/ + +CREATE OR REPLACE FUNCTION unapi.mmr ( + mmr_id BIGINT, + format TEXT, + ename TEXT, + includes TEXT[], + org TEXT, + depth INT DEFAULT NULL, + slimit HSTORE DEFAULT NULL, + soffset HSTORE DEFAULT NULL, + include_xmlns BOOL DEFAULT TRUE, + pref_lib INT DEFAULT NULL +) +RETURNS XML AS $F$ +DECLARE + mmrec metabib.metarecord%ROWTYPE; + leadrec biblio.record_entry%ROWTYPE; + subrec biblio.record_entry%ROWTYPE; + layout unapi.bre_output_layout%ROWTYPE; + xfrm config.xml_transform%ROWTYPE; + ouid INT; + xml_buf TEXT; -- growing XML document + tmp_xml TEXT; -- single-use XML string + xml_frag TEXT; -- single-use XML fragment + top_el TEXT; + output XML; + hxml XML; + axml XML; + subxml XML; -- subordinate records elements + sub_xpath TEXT; +BEGIN + + -- xpath for extracting bre.marc values from subordinate records + -- so they may be appended to the MARC of the master record prior + -- to XSLT processing. + -- subjects, isbn, issn, upc -- anything else? + sub_xpath := + '//*[starts-with(@tag, "6") or @tag="020" or @tag="022" or @tag="024"]'; + + IF org = '-' OR org IS NULL THEN + SELECT shortname INTO org FROM evergreen.org_top(); + END IF; + + SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org; + + IF ouid IS NULL THEN + RETURN NULL::XML; + END IF; + + SELECT INTO mmrec * FROM metabib.metarecord WHERE id = mmr_id; + IF NOT FOUND THEN + RETURN NULL::XML; + END IF; + + /* + -- TODO: aggregate holdings from constituent records + IF format = 'holdings_xml' THEN -- the special case + output := unapi.holdings_xml( + mmr_id, ouid, org, depth, includes, slimit, soffset, include_xmlns); + RETURN output; + END IF; + */ + + SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format; + + IF layout.name IS NULL THEN + RETURN NULL::XML; + END IF; + + SELECT * INTO xfrm FROM config.xml_transform WHERE name = layout.transform; + + SELECT INTO leadrec * FROM biblio.record_entry WHERE id = mmrec.master_record; + + -- Grab bulk SVF for the lead record if requested + -- TODO: additional SVF values from constituent records for formats, etc. + IF ('mra' = ANY (includes)) THEN + axml := unapi.mra(leadrec.id,NULL,NULL,NULL,NULL); + ELSE + axml := NULL::XML; + END IF; + + xml_buf = leadrec.marc; + + hxml := NULL::XML; + subxml := NULL::XML; + FOR subrec IN SELECT * FROM biblio.record_entry bre + JOIN metabib.metarecord_source_map mmsm ON (mmsm.metarecord = mmr_id) + WHERE mmsm.source = bre.id LOOP + + -- collect holdings for all records + -- XXX: holdings limits and offsets are applied individually to each + -- subordinate record. This could lead to large XML blobs for + -- large metarecords. Does this need to change? + IF ('holdings_xml' = ANY (includes)) THEN + hxml := XMLCONCAT(hxml, unapi.holdings_xml( + subrec.id, ouid, org, depth, + evergreen.array_remove_item_by_value(includes,'holdings_xml'), + slimit, soffset, include_xmlns, pref_lib)); + END IF; + + IF subrec.id = leadrec.id THEN CONTINUE; END IF; + -- Append choice data from the XML of the non-lead records to the + -- XML of the lead record + + FOREACH xml_frag IN ARRAY + (SELECT * FROM xpath(sub_xpath, subrec.marc::XML)) LOOP + subxml := XMLCONCAT(subxml, xml_frag::XML); + END LOOP; + END LOOP; + + -- append data from the subordinate records to the + -- record document before applying the main XSLT + + top_el := REGEXP_REPLACE(xml_buf, E'^.*?<((?:\\S+:)?' || + layout.holdings_element || ').*$', E'\\1'); + + IF subxml IS NOT NULL THEN + xml_buf := REGEXP_REPLACE(xml_buf, + '(.*?)$', subxml || '\\1'); + END IF; + + IF format = 'marcxml' THEN + -- If we're not using the prefixed namespace in + -- this record, then remove all declarations of it + IF xml_buf !~ E'(.*?)$', axml || '\\1'); + END IF; + + IF hxml IS NOT NULL THEN -- XXX how do we configure the holdings position? + xml_buf := REGEXP_REPLACE(xml_buf, + '(.*?)$', hxml || '\\1'); + END IF; + + IF ('mmr.unapi' = ANY (includes)) THEN + output := REGEXP_REPLACE( + xml_buf, + '(.*?)', + XMLELEMENT( + name abbr, + XMLATTRIBUTES( + 'http://www.w3.org/1999/xhtml' AS xmlns, + 'unapi-id' AS class, + 'tag:open-ils.org:U2@mmr/' || mmr_id || '/' || org AS title + ) + )::TEXT || '\\1' + ); + ELSE + output := xml_buf; + END IF; + + output := REGEXP_REPLACE(output::TEXT,E'>\\s+<','><','gs')::XML; + RETURN output; +END; +$F$ LANGUAGE PLPGSQL STABLE; + +COMMIT;