UNPKG

@natlibfi/melinda-record-match-validator

Version:

Validates if two records matched by melinda-record-matching can be merged and sets merge priority

226 lines (212 loc) 8.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.check773 = check773; exports.check773Internal = check773Internal; exports.compare773 = compare773; exports.get773 = get773; var _debug = _interopRequireDefault(require("debug")); var _collectUtils = require("./collectFunctions/collectUtils"); var _utils = require("./utils"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const debug = (0, _debug.default)('@natlibfi/melinda-record-match-validator:field773'); const debugDev = debug.extend('dev'); //const debugData = debug.extend('data'); function getX73(record, paramTag) { // Tag should be 773 or 973. Add sanity check? const F773s = (0, _collectUtils.hasFields)(paramTag, record, f773ToJSON); debugDev('Field %ss: %o', paramTag, F773s); return F773s; function f773ToJSON(f773) { // NB! Test multiple 773 fields as well! const tag = paramTag; // NB! It is legal to have multiple $w subfields in a field! // Eg. We oft see both Arto and Melinda ID in the same record. const recordControlNumbers = getRecordControlNumbers(f773); // $g and $q are non-repeatable: const relatedParts = (0, _collectUtils.getSubfield)(f773, 'g'); const enumerationAndFirstPage = (0, _collectUtils.getSubfield)(f773, 'q'); return { tag, recordControlNumbers, relatedParts, enumerationAndFirstPage }; } function getRecordControlNumbers(field) { // Get normalized subfields that have an record control number with a source identifier: const wSubfields = (0, _collectUtils.getSubfieldValues)(field, 'w').map(value => (0, _utils.normalizeMelindaId)(value)) // normalize, though filter would succeed anyway .filter(value => !/^[0-9]+$/u.test(value)); // Filter digit-only values away return wSubfields; } } function get773(record) { // collect const f773 = getX73(record, '773'); // get also Viola's multihost host link fields from f973 const f973 = getX73(record, '973'); return [...f773, ...f973]; } // failMultipleHostLinks: fail if there are multiple host links in either record // failF973: fail if record has a f973 (Viola's multihost records have f973 for extra host links) // requireHostIdMatch: fail if records do not have a common internal host id (incoming record should have pre-created matching host id with database record) // failHostIdMatch: fail if records have a common internal host id (two database records should generally not have matching host ids) // default options to original functionality (fail multiples, f973 and id mismatches, but do not require a match) function check773({ record1, record2, failMultipleHostLinks = true, failF973 = true, requireHostIdMatch = false, failHostIdMatch = false }) { const data1 = get773(record1); const data2 = get773(record2); return compare773values({ f773sA: data1, f773sB: data2, failMultipleHostLinks, failF973, requireHostIdMatch, failHostIdMatch }); } // For internal merge (merging two database records, do not fail multiple f773/f973 or f973 existence // do not require common internal host id, fail if records have a common internal host id) function check773Internal({ record1, record2, failMultipleHostLinks = false, failF973 = false, requireHostIdMatch = false, failHostIdMatch = true }) { const data1 = get773(record1); const data2 = get773(record2); return compare773values({ f773sA: data1, f773sB: data2, failMultipleHostLinks, failF973, requireHostIdMatch, failHostIdMatch }); } // default options to original functionality function compare773values({ f773sA, f773sB, failMultipleHostLinks = true, failF973 = true, requireHostIdMatch = false, failHostIdMatch = false }) { debugDev('Collected f773s: %o vs %o', f773sA, f773sB); (0, _utils.nvdebug)('compare773values() in...', debugDev); (0, _utils.nvdebug)(JSON.stringify(f773sA), debugDev); (0, _utils.nvdebug)(JSON.stringify(f773sB), debugDev); // Fail if one of the records has multiple 773/973 fields: // (Multiple 773 fields means that it's a Viola record, or that some weeding is need first.) if (failMultipleHostLinks && (f773sA.length > 1 || f773sB.length > 1)) { return false; } // Fail if one of the fields is 973 if (failF973 && (f773sA.some(val => val.tag === '973') || f773sB.some(val => val.tag === '973'))) { return false; } /* if (f773sA.length > 0 && f773sB.length === 0) { return true; // return 'A'; } if (f773sB.length > 0 && f773sA.length === 0) { return true; // return 'B'; } if (f773sA.length === 0 && f773sB.length === 0) { return true; } */ if (f773sA.length === 0 || f773sB.length === 0) { return true; } const undefinedHack = (0, _collectUtils.getDefaultMissValue)(); // String 'undefined' return innerCompare({ data1: f773sA[0], data2: f773sB[0], requireHostIdMatch, failHostIdMatch }); function noMultivals(val1, val2) { (0, _utils.nvdebug)(`compare '${val1}' vs '${val2}' (default: '${undefinedHack}')`, debugDev); return val1 === val2 || !val1 || !val2 || val1 === undefinedHack || val2 === undefinedHack; } // nums1, nums2 record 773w/973w contents (plain numbers filtered out) function acceptControlNumbers({ nums1, nums2, requireHostIdMatch, failHostIdMatch }) { debugDev(`Comparing host controlnumbers: ${JSON.stringify(nums1)} to ${JSON.stringify(nums2)}}`); debugDev(`Settings: requireHostIdMatch: ${requireHostIdMatch}, failHostIdMatch: ${failHostIdMatch}`); // Handling internal host ids depends on requireHostIdMatch and failHostIdMatch parameters // - mergeing incoming and database record should have a common internal host id match pre-inserted to incoming record // - mergeing two database records should not have a common internal host id if we're merging whole record family if (requireHostIdMatch || failHostIdMatch) { const { internalIds: internalIds1, otherIds: otherIds1 } = (0, _utils.splitIds)(nums1); const { internalIds: internalIds2, otherIds: otherIds2 } = (0, _utils.splitIds)(nums2); const internalHostIdMatch = internalIds1.some(val => (0, _utils.hasIdMatch)(val, internalIds2)) || internalIds2.some(val => (0, _utils.hasIdMatch)(val, internalIds1)); const internalHostIdMismatch = internalIds1.some(val => (0, _utils.hasIdMismatch)(val, internalIds2)) || internalIds2.some(val => (0, _utils.hasIdMismatch)(val, internalIds1)); // fail if there is an internal id match we do not want if (failHostIdMatch && internalHostIdMatch) { return false; } // fail if there are no internal id matches if (requireHostIdMatch && !internalHostIdMatch) { return false; } if (internalHostIdMismatch) { return false; } // true if there are no idMismatches in other host ids between records return !(otherIds1.some(val => (0, _utils.hasIdMismatch)(val, otherIds2)) || otherIds2.some(val2 => (0, _utils.hasIdMismatch)(val2, otherIds1))); } // true if there are no idMismatches between records return !(nums1.some(val => (0, _utils.hasIdMismatch)(val, nums2)) || nums2.some(val2 => (0, _utils.hasIdMismatch)(val2, nums1))); } function innerCompare({ data1, data2, requireHostIdMatch, failHostIdMatch }) { const recordControlNumbers = acceptControlNumbers({ nums1: data1.recordControlNumbers, nums2: data2.recordControlNumbers, requireHostIdMatch, failHostIdMatch }); (0, _utils.nvdebug)(`RECORD CONTROL NUMBERS ${recordControlNumbers}`, debugDev); // $g and $q are optional: const relatedParts = noMultivals(data1.relatedParts, data2.relatedParts); const enumerationAndFirstPage = noMultivals(data1.enumerationAndFirstPage, data2.enumerationAndFirstPage); (0, _utils.nvdebug)(`RCN ${recordControlNumbers}\tRP ${relatedParts ? 'true' : 'false'}\tEAFP ${enumerationAndFirstPage ? 'true' : 'false'}`, debugDev); (0, _utils.nvdebug)(`SOME RESULT: ${enumerationAndFirstPage && recordControlNumbers && relatedParts ? 'true' : 'false'}`, debugDev); return enumerationAndFirstPage && recordControlNumbers && relatedParts; } } function compare773(recordValuesA = [], recordValuesB = []) { const f773sA = recordValuesA['773']; const f773sB = recordValuesB['773']; return compare773values({ f773sA, f773sB }); } //# sourceMappingURL=field773.js.map