1 | const { isNumber, chunk, flatten } = require('lodash');
|
2 | const delay = require('./delay');
|
3 |
|
4 | module.exports = function batchInsert(
|
5 | client,
|
6 | tableName,
|
7 | batch,
|
8 | chunkSize = 1000
|
9 | ) {
|
10 | let returning = void 0;
|
11 | let transaction = null;
|
12 |
|
13 | const runInTransaction = (cb) => {
|
14 | if (transaction) {
|
15 | return cb(transaction);
|
16 | }
|
17 | return client.transaction(cb);
|
18 | };
|
19 |
|
20 | return Object.assign(
|
21 | Promise.resolve().then(async () => {
|
22 | if (!isNumber(chunkSize) || chunkSize < 1) {
|
23 | throw new TypeError(`Invalid chunkSize: ${chunkSize}`);
|
24 | }
|
25 |
|
26 | if (!Array.isArray(batch)) {
|
27 | throw new TypeError(
|
28 | `Invalid batch: Expected array, got ${typeof batch}`
|
29 | );
|
30 | }
|
31 |
|
32 | const chunks = chunk(batch, chunkSize);
|
33 |
|
34 |
|
35 | await delay(1);
|
36 | return runInTransaction(async (tr) => {
|
37 | const chunksResults = [];
|
38 | for (const items of chunks) {
|
39 | chunksResults.push(await tr(tableName).insert(items, returning));
|
40 | }
|
41 | return flatten(chunksResults);
|
42 | });
|
43 | }),
|
44 | {
|
45 | returning(columns) {
|
46 | returning = columns;
|
47 |
|
48 | return this;
|
49 | },
|
50 | transacting(tr) {
|
51 | transaction = tr;
|
52 |
|
53 | return this;
|
54 | },
|
55 | }
|
56 | );
|
57 | };
|