UNPKG

knex

Version:

A batteries-included SQL query & schema builder for Postgres, MySQL and SQLite3 and the Browser

85 lines (71 loc) 2.09 kB
import { isNumber, isArray, chunk, flatten, assign } from 'lodash'; import Promise from 'bluebird'; export default function batchInsert( client, tableName, batch, chunkSize = 1000 ) { let returning = void 0; let autoTransaction = true; let transaction = null; 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; }, } ); return wrapper; }