knex/src/util/batchInsert.js

78 lines
2.1 KiB
JavaScript
Raw Normal View History

'use strict';
import {isNumber, isString, isArray, chunk, flatten} from 'lodash';
import Promise from '../promise';
export default class BatchInsert {
2016-05-09 22:38:56 +02:00
constructor(client, tableName, batch, chunkSize = 1000) {
if(!isNumber(chunkSize) || chunkSize < 1) {
throw new TypeError(`Invalid chunkSize: ${chunkSize}`);
}
2016-05-09 22:38:56 +02:00
if(!isArray(batch)) {
throw new TypeError(`Invalid batch: Expected array, got ${typeof batch}`)
}
2016-05-10 08:41:06 +02:00
this.client = client;
this.tableName = tableName;
this.batch = chunk(batch, chunkSize);
this._returning = void 0;
this._transaction = null;
this._autoTransaction = true;
2016-05-11 13:31:14 +02:00
2016-05-09 22:38:56 +02:00
}
2016-05-09 22:38:56 +02:00
/**
* Columns to return from the batch operation.
* @param returning
*/
returning(returning) {
if(isArray(returning) || isString(returning)) {
this._returning = returning;
}
return this;
}
2016-05-09 22:38:56 +02:00
/**
* User may supply their own transaction.
2016-05-10 08:41:06 +02:00
* If this is the case, autoTransaction = false, meaning we don't automatically commit/rollback the transaction. The responsibility instead falls on the user.
2016-05-09 22:38:56 +02:00
* @param transaction
*/
transacting(transaction) {
2016-05-10 08:41:06 +02:00
this._transaction = transaction;
this._autoTransaction = false;
2016-05-09 22:38:56 +02:00
return this;
}
2016-05-10 08:41:06 +02:00
_getTransaction() {
2016-05-11 13:36:25 +02:00
return new Promise((resolve) => {
2016-05-10 08:41:06 +02:00
if(this._transaction) {
return resolve(this._transaction);
}
this.client.transaction((tr) => resolve(tr));
});
}
2016-05-09 22:38:56 +02:00
then(callback = function() {}) {
2016-05-10 08:41:06 +02:00
return this._getTransaction()
.then((transaction) => {
2016-05-09 22:38:56 +02:00
return Promise.all(this.batch.map((items) => {
2016-05-11 17:49:18 +02:00
return transaction(this.tableName)
.insert(items, this._returning);
2016-05-10 08:41:06 +02:00
}))
.then((result) => {
if(this._autoTransaction) {
transaction.commit();
}
return callback(flatten(result || []));
})
.catch((error) => {
if(this._autoTransaction) {
transaction.rollback(error);
}
throw error;
});
2016-05-09 22:38:56 +02:00
});
}
2016-05-11 13:31:14 +02:00
}