2017-03-22 21:44:36 +01:00
|
|
|
import { isNumber, isArray, chunk, flatten, assign } from 'lodash';
|
2016-08-09 17:23:07 -04:00
|
|
|
import Promise from 'bluebird';
|
2016-05-09 19:01:00 +02:00
|
|
|
|
2018-07-09 08:10:34 -04:00
|
|
|
export default function batchInsert(
|
|
|
|
client,
|
|
|
|
tableName,
|
|
|
|
batch,
|
|
|
|
chunkSize = 1000
|
|
|
|
) {
|
2017-03-22 21:44:36 +01:00
|
|
|
let returning = void 0;
|
|
|
|
let autoTransaction = true;
|
|
|
|
let transaction = null;
|
|
|
|
|
2018-07-09 08:10:34 -04:00
|
|
|
const getTransaction = () =>
|
|
|
|
new Promise((resolve, reject) => {
|
|
|
|
if (transaction) {
|
|
|
|
autoTransaction = false;
|
|
|
|
return resolve(transaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
autoTransaction = true;
|
|
|
|
client.transaction(resolve).catch(reject);
|
|
|
|
});
|
|
|
|
|
|
|
|
const wrapper = assign(
|
|
|
|
new Promise((resolve, reject) => {
|
|
|
|
const chunks = chunk(batch, chunkSize);
|
|
|
|
|
|
|
|
if (!isNumber(chunkSize) || chunkSize < 1) {
|
|
|
|
return reject(new TypeError(`Invalid chunkSize: ${chunkSize}`));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isArray(batch)) {
|
|
|
|
return reject(
|
|
|
|
new TypeError(`Invalid batch: Expected array, got ${typeof batch}`)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Next tick to ensure wrapper functions are called if needed
|
|
|
|
return Promise.delay(1)
|
|
|
|
.then(getTransaction)
|
|
|
|
.then((tr) => {
|
|
|
|
return Promise.mapSeries(chunks, (items) =>
|
|
|
|
tr(tableName).insert(items, returning)
|
|
|
|
)
|
|
|
|
.then((result) => {
|
|
|
|
result = flatten(result || []);
|
|
|
|
|
|
|
|
if (autoTransaction) {
|
|
|
|
//TODO: -- Oracle tr.commit() does not return a 'thenable' !? Ugly hack for now.
|
|
|
|
return (tr.commit(result) || Promise.resolve()).then(
|
|
|
|
() => result
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
if (autoTransaction) {
|
|
|
|
return tr.rollback(error).then(() => Promise.reject(error));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.reject(error);
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.then(resolve)
|
|
|
|
.catch(reject);
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
returning(columns) {
|
|
|
|
returning = columns;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
transacting(tr) {
|
|
|
|
transaction = tr;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
2017-03-22 21:44:36 +01:00
|
|
|
}
|
2018-07-09 08:10:34 -04:00
|
|
|
);
|
2017-03-22 21:44:36 +01:00
|
|
|
|
|
|
|
return wrapper;
|
2017-03-24 10:52:38 +01:00
|
|
|
}
|