UNPKG

3.75 kBJavaScriptView Raw
1'use strict';
2
3const common = require('./common');
4const BulkOperationBase = common.BulkOperationBase;
5const Batch = common.Batch;
6const bson = common.bson;
7const utils = require('../utils');
8const toError = utils.toError;
9
10/**
11 * Add to internal list of Operations
12 *
13 * @ignore
14 * @param {OrderedBulkOperation} bulkOperation
15 * @param {number} docType number indicating the document type
16 * @param {object} document
17 * @return {OrderedBulkOperation}
18 */
19function addToOperationsList(bulkOperation, docType, document) {
20 // Get the bsonSize
21 const bsonSize = bson.calculateObjectSize(document, {
22 checkKeys: false,
23
24 // Since we don't know what the user selected for BSON options here,
25 // err on the safe side, and check the size with ignoreUndefined: false.
26 ignoreUndefined: false
27 });
28
29 // Throw error if the doc is bigger than the max BSON size
30 if (bsonSize >= bulkOperation.s.maxBsonObjectSize)
31 throw toError('document is larger than the maximum size ' + bulkOperation.s.maxBsonObjectSize);
32
33 // Create a new batch object if we don't have a current one
34 if (bulkOperation.s.currentBatch == null)
35 bulkOperation.s.currentBatch = new Batch(docType, bulkOperation.s.currentIndex);
36
37 const maxKeySize = bulkOperation.s.maxKeySize;
38
39 // Check if we need to create a new batch
40 if (
41 // New batch if we exceed the max batch op size
42 bulkOperation.s.currentBatchSize + 1 >= bulkOperation.s.maxWriteBatchSize ||
43 // New batch if we exceed the maxBatchSizeBytes. Only matters if batch already has a doc,
44 // since we can't sent an empty batch
45 (bulkOperation.s.currentBatchSize > 0 &&
46 bulkOperation.s.currentBatchSizeBytes + maxKeySize + bsonSize >=
47 bulkOperation.s.maxBatchSizeBytes) ||
48 // New batch if the new op does not have the same op type as the current batch
49 bulkOperation.s.currentBatch.batchType !== docType
50 ) {
51 // Save the batch to the execution stack
52 bulkOperation.s.batches.push(bulkOperation.s.currentBatch);
53
54 // Create a new batch
55 bulkOperation.s.currentBatch = new Batch(docType, bulkOperation.s.currentIndex);
56
57 // Reset the current size trackers
58 bulkOperation.s.currentBatchSize = 0;
59 bulkOperation.s.currentBatchSizeBytes = 0;
60 }
61
62 if (docType === common.INSERT) {
63 bulkOperation.s.bulkResult.insertedIds.push({
64 index: bulkOperation.s.currentIndex,
65 _id: document._id
66 });
67 }
68
69 // We have an array of documents
70 if (Array.isArray(document)) {
71 throw toError('operation passed in cannot be an Array');
72 }
73
74 bulkOperation.s.currentBatch.originalIndexes.push(bulkOperation.s.currentIndex);
75 bulkOperation.s.currentBatch.operations.push(document);
76 bulkOperation.s.currentBatchSize += 1;
77 bulkOperation.s.currentBatchSizeBytes += maxKeySize + bsonSize;
78 bulkOperation.s.currentIndex += 1;
79
80 // Return bulkOperation
81 return bulkOperation;
82}
83
84/**
85 * Create a new OrderedBulkOperation instance (INTERNAL TYPE, do not instantiate directly)
86 * @class
87 * @extends BulkOperationBase
88 * @property {number} length Get the number of operations in the bulk.
89 * @return {OrderedBulkOperation} a OrderedBulkOperation instance.
90 */
91class OrderedBulkOperation extends BulkOperationBase {
92 constructor(topology, collection, options) {
93 options = options || {};
94 options = Object.assign(options, { addToOperationsList });
95
96 super(topology, collection, options, true);
97 }
98}
99
100/**
101 * Returns an unordered batch object
102 * @ignore
103 */
104function initializeOrderedBulkOp(topology, collection, options) {
105 return new OrderedBulkOperation(topology, collection, options);
106}
107
108initializeOrderedBulkOp.OrderedBulkOperation = OrderedBulkOperation;
109module.exports = initializeOrderedBulkOp;
110module.exports.Bulk = OrderedBulkOperation;