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 19:03:48 +02:00
|
|
|
constructor(client, tableName, batch, chunkSize = 1000) {
|
|
|
|
if(!isNumber(chunkSize) || chunkSize < 1) {
|
2016-05-09 19:01:00 +02:00
|
|
|
throw new TypeError(`Invalid chunkSize: ${chunkSize}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!isArray(batch)) {
|
|
|
|
throw new TypeError(`Invalid batch: Expected array, got ${typeof batch}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
this.client = client;
|
|
|
|
this.tableName = tableName;
|
|
|
|
this.batch = chunk(batch, chunkSize);
|
|
|
|
this._returning = void 0;
|
|
|
|
this._transaction = null;
|
|
|
|
this._autoCommit = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Columns to return from the batch operation.
|
|
|
|
* @param returning
|
|
|
|
*/
|
2016-05-09 19:03:48 +02:00
|
|
|
returning(returning) {
|
2016-05-09 19:01:00 +02:00
|
|
|
if(isArray(returning) || isString(returning)) {
|
|
|
|
this._returning = returning;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* User may supply their own transaction.
|
|
|
|
* If this is the case, don't autoCommit their transaction. The responsibility falls on the user.
|
|
|
|
* @param transaction
|
|
|
|
*/
|
2016-05-09 19:03:48 +02:00
|
|
|
transacting(transaction) {
|
2016-05-09 19:01:00 +02:00
|
|
|
this._transaction = transaction;
|
2016-05-09 19:03:48 +02:00
|
|
|
this._autoCommit = false;
|
2016-05-09 19:01:00 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2016-05-09 19:03:48 +02:00
|
|
|
then(callback = function() {}) {
|
2016-05-09 19:01:00 +02:00
|
|
|
let transaction;
|
|
|
|
return Promise.resolve()
|
2016-05-09 19:03:48 +02:00
|
|
|
.then(() => {
|
2016-05-09 19:01:00 +02:00
|
|
|
if(this._transaction) {
|
|
|
|
transaction = this._transaction;
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
this.client.transaction((tr) => {
|
|
|
|
transaction = tr;
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
})
|
2016-05-09 19:03:48 +02:00
|
|
|
.then(() => {
|
2016-05-09 19:01:00 +02:00
|
|
|
return Promise.all(this.batch.map((items) => {
|
|
|
|
let promise = transaction(this.tableName)
|
|
|
|
.insert(items);
|
|
|
|
if(this._returning) {
|
|
|
|
promise.returning(this._returning);
|
|
|
|
}
|
|
|
|
return promise;
|
|
|
|
}));
|
2016-05-09 19:03:48 +02:00
|
|
|
})
|
|
|
|
.then((result) => {
|
2016-05-09 19:01:00 +02:00
|
|
|
if(this._autoCommit) {
|
|
|
|
transaction.commit();
|
|
|
|
}
|
|
|
|
return callback(flatten(result || []));
|
2016-05-09 19:03:48 +02:00
|
|
|
})
|
2016-05-09 19:01:00 +02:00
|
|
|
.catch((error) => {
|
|
|
|
if(this._autoCommit) {
|
|
|
|
transaction.rollback(error);
|
|
|
|
}
|
|
|
|
throw error;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|