UNPKG

@360-l/mongo-bulk-data-migration

Version:
128 lines (127 loc) 6.15 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.computeRollbackQuery = computeRollbackQuery; const lodash_1 = __importDefault(require("lodash")); const flattenDocument_1 = require("../tools/flattenDocument"); const arrayFiltersUtils = __importStar(require("../tools/arrayFilters")); function computeRollbackQuery(updateQuery, backup) { const unsetPropertiesDuringUpdate = Object.keys(updateQuery.$unset || {}); const setPropertiesDuringUpdate = Object.keys(updateQuery.$set || {}); const $set = computeRollbackSet(setPropertiesDuringUpdate, unsetPropertiesDuringUpdate, backup); const $unsetWithoutPositionals = computeRollbackUnset(setPropertiesDuringUpdate, backup, $set); const { arrayFilters, unsetAdditionalPositional } = _computeArrayFilterAndUnsetWithPositionals(updateQuery, backup); const $unset = { ...$unsetWithoutPositionals, ...unsetAdditionalPositional, }; return { ...(!lodash_1.default.isEmpty($set) ? { $set } : {}), ...(!lodash_1.default.isEmpty($unset) ? { $unset } : {}), ...(!lodash_1.default.isEmpty(arrayFilters) ? { arrayFilters } : {}), }; } function _computeArrayFilterAndUnsetWithPositionals(updateQuery, backup) { const unsetAdditionalPositional = {}; const filteredObject = Object.keys((0, flattenDocument_1.flattenDocument)(backup)); const arrayFilters = []; const update = Object.keys((0, flattenDocument_1.flattenDocument)(updateQuery.$set ?? {})); update .filter((path) => !filteredObject.includes(path) && !arrayFiltersUtils.hasPathMatchingPositionalOperators(path, filteredObject)) .forEach((path) => { if (arrayFiltersUtils.isArrayFilterPath(path)) { unsetAdditionalPositional[path] = 1; arrayFilters.push(...arrayFiltersUtils.buildArrayFiltersOptionToUnset(path)); } }); return { arrayFilters, unsetAdditionalPositional, }; } function computeRollbackSet(setPropertiesDuringUpdate, unsetPropertiesDuringUpdate, backup) { const flattenBackupDocument = (0, flattenDocument_1.flattenDocument)(backup); return Object.entries(flattenBackupDocument).reduce((rollbackSet, [key, value]) => { const parentKeyToFullyRestore = [ ...setPropertiesDuringUpdate, ...unsetPropertiesDuringUpdate ].find((setOrUnsetKey) => key.startsWith(`${setOrUnsetKey}.`)); if (parentKeyToFullyRestore && parentKeyToFullyRestore in backup) { rollbackSet[parentKeyToFullyRestore] = backup[parentKeyToFullyRestore]; return rollbackSet; } const indexMatch = /(.*)\.(\d+)$/.exec(key); if (indexMatch) { const [_str, nestedPathToArray, index] = indexMatch; if (Array.isArray(lodash_1.default.get(backup, nestedPathToArray))) { const containsDeeperSubKey = setPropertiesDuringUpdate.some((propertySet) => propertySet !== key && propertySet.match(new RegExp(`^${nestedPathToArray}\\.\\d+\\.`))); if (!containsDeeperSubKey) { if (typeof rollbackSet[nestedPathToArray] === 'undefined') { rollbackSet[nestedPathToArray] = []; } rollbackSet[nestedPathToArray][Number(index)] = value; } else { rollbackSet[`${nestedPathToArray}.${index}`] = value; } return rollbackSet; } } rollbackSet[key] = value; return rollbackSet; }, {}); } function computeRollbackUnset(setPropertiesDuringUpdate, backup, $set) { const keysToSet = Object.keys($set); const keysToUnset = setPropertiesDuringUpdate.filter((path) => !keysToSet.includes(path) && !arrayFiltersUtils.isArrayFilterPath(path) && !keysToSet.some((key) => path.startsWith(`${key}.`))); const parentKeysToUnset = computeParentKeysToUnset(keysToUnset, backup); const nonConflictingKeysToUnset = filterConflictingKeys([ ...keysToUnset, ...parentKeysToUnset, ]); const entriesToUnset = nonConflictingKeysToUnset.map((key) => [key, 1]); return Object.fromEntries(entriesToUnset); } function computeParentKeysToUnset(nestedKeysToUnset, backup) { return nestedKeysToUnset.reduce((parentKeysToUnset, key) => { const splitParentKeys = key.split('.').slice(0, -1); const parentKeyNestedPaths = splitParentKeys.map((_key, offset) => splitParentKeys.slice(0, offset + 1).join('.')); const keysToUnset = parentKeyNestedPaths.filter((parentKey) => !lodash_1.default.has(backup, parentKey)); return parentKeysToUnset.concat(keysToUnset); }, []); } function filterConflictingKeys(keys) { return keys.filter((key) => { const nestedParentKey = key.split('.').slice(0, -1).join('.'); return !keys.includes(nestedParentKey); }); }