knex-utils
Version:
Useful utilities for Knex.js
102 lines • 3.57 kB
JavaScript
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
;