2016-05-09 19:01:00 +02:00
|
|
|
'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 19:01:00 +02:00
|
|
|
|
2016-05-09 22:38:56 +02:00
|
|
|
if(!isArray(batch)) {
|
|
|
|
throw new TypeError(`Invalid batch: Expected array, got ${typeof batch}`)
|
|
|
|
}
|
2016-05-09 19:01:00 +02:00
|
|
|
|
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 19:01:00 +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 19:01:00 +02:00
|
|
|
|
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-09 19:01:00 +02:00
|
|
|
|
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
|
|
|
}
|