UNPKG

knex-utils

Version:

Useful utilities for Knex.js

102 lines 3.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateJoinTable = exports.calculateEntityListDiff = void 0; const objectUtils_1 = require("./objectUtils"); const chunkUtils_1 = require("./chunkUtils"); function arrayIncludesWith(array, target, comparator) { if (array == null) { return false; } for (const value of array) { if (comparator(target, value)) { return true; } } return false; } function baseDifference(initialArray, newArray, comparator) { const includes = arrayIncludesWith; const newEntries = []; const removedEntries = []; for (const value of initialArray) { if (!includes(newArray, value, comparator)) { removedEntries.push(value); } } for (const value of newArray) { if (!includes(initialArray, value, comparator)) { newEntries.push(value); } } return { removedEntries, newEntries, }; } function calculateEntityListDiff(oldList, newList, idFields) { const comparator = (value1, value2) => { for (const idField of idFields) { if (value1[idField] !== value2[idField]) { return false; } } return true; }; return baseDifference(oldList, newList, comparator); } exports.calculateEntityListDiff = calculateEntityListDiff; async function getKnexOrTrx(knex, params) { if (knex.client.driverName === 'sqlite3') { return knex; } if (params.transaction) { return params.transaction; } if (params.transactionProvider) { return params.transactionProvider(); } return knex.transaction(); } async function updateJoinTable(knex, newList, params) { const chunkSize = params.chunkSize || 100; const trx = await getKnexOrTrx(knex, params); try { const oldList = await trx(params.table).select('*').where(params.filterCriteria); const diff = calculateEntityListDiff(oldList, newList, params.idFields); const insertChunks = (0, chunkUtils_1.chunk)(diff.newEntries, chunkSize); for (const insertChunk of insertChunks) { await trx(params.table).insert(insertChunk); } // If we have a primary key, then we can delete in batch if (params.primaryKeyField) { const deleteIds = diff.removedEntries.map((entry) => { return entry[params.primaryKeyField]; }); const deleteChunks = (0, chunkUtils_1.chunk)(deleteIds, chunkSize); for (const deleteChunk of deleteChunks) { await trx(params.table).delete().whereIn(params.primaryKeyField, deleteChunk); } } // Otherwise we have to delete one-by-one else { const deleteCriteria = diff.removedEntries.map((entry) => { return (0, objectUtils_1.pick)(entry, params.idFields); }); for (const entry of deleteCriteria) { await trx(params.table).delete().where(entry); } } if (trx.isTransaction && !params.transaction && !params.transactionProvider) { await trx.commit(); } return diff; } catch (err) { if (trx.isTransaction) { await trx.rollback(); } throw err; } } exports.updateJoinTable = updateJoinTable; //# sourceMappingURL=diffUtils.js.map