diff --git a/src/bulk/common.ts b/src/bulk/common.ts index df015577e5..00e5dee4e6 100644 --- a/src/bulk/common.ts +++ b/src/bulk/common.ts @@ -165,50 +165,51 @@ export class Batch { export class BulkWriteResult { result: BulkResult; - /** Indicates whether this write result was acknowledged. If not, then all other members of this result will be undefined */ - // acknowledged: Boolean; - /** Number of documents inserted. */ - insertedCount: number; - /** Number of documents matched for update. */ - matchedCount: number; - /** Number of documents modified. */ - modifiedCount: number; - /** Number of documents deleted. */ - deletedCount: number; - /** Number of documents upserted. */ - upsertedCount: number; - /** Inserted document generated Id's, hash key is the index of the originating operation */ - insertedIds: { [key: number]: ObjectId }; - /** Upserted document generated Id's, hash key is the index of the originating operation */ - upsertedIds: { [key: number]: ObjectId }; - /** * Create a new BulkWriteResult instance * @internal */ constructor(bulkResult: BulkResult) { this.result = bulkResult; - this.insertedCount = bulkResult.nInserted; - this.matchedCount = bulkResult.nMatched; - this.modifiedCount = bulkResult.nModified || 0; - this.deletedCount = bulkResult.nRemoved; - this.upsertedCount = bulkResult.upserted.length; - this.upsertedIds = {}; - this.insertedIds = {}; - - // Inserted documents - const inserted = bulkResult.insertedIds; - // Map inserted ids - for (let i = 0; i < inserted.length; i++) { - this.insertedIds[inserted[i].index] = inserted[i]._id; + } + + /** Number of documents inserted. */ + get insertedCount(): number { + return this.result.nInserted ?? 0; + } + /** Number of documents matched for update. */ + get matchedCount(): number { + return this.result.nMatched ?? 0; + } + /** Number of documents modified. */ + get modifiedCount(): number { + return this.result.nModified ?? 0; + } + /** Number of documents deleted. */ + get deletedCount(): number { + return this.result.nRemoved ?? 0; + } + /** Number of documents upserted. */ + get upsertedCount(): number { + return this.result.upserted.length ?? 0; + } + + /** Upserted document generated Id's, hash key is the index of the originating operation */ + get upsertedIds(): { [key: number]: any } { + const upserted: { [index: number]: any } = {}; + for (const doc of this.result.upserted ?? []) { + upserted[doc.index] = doc._id; } + return upserted; + } - // Upserted documents - const upserted = bulkResult.upserted; - // Map upserted ids - for (let i = 0; i < upserted.length; i++) { - this.upsertedIds[upserted[i].index] = upserted[i]._id; + /** Inserted document generated Id's, hash key is the index of the originating operation */ + get insertedIds(): { [key: number]: any } { + const inserted: { [index: number]: any } = {}; + for (const doc of this.result.insertedIds ?? []) { + inserted[doc.index] = doc._id; } + return inserted; } /** Evaluates to true if the bulk operation correctly executes */ @@ -674,21 +675,6 @@ function handleMongoWriteConcernError( export class MongoBulkWriteError extends MongoError { result: BulkWriteResult; - /** Number of documents inserted. */ - insertedCount: number; - /** Number of documents matched for update. */ - matchedCount: number; - /** Number of documents modified. */ - modifiedCount: number; - /** Number of documents deleted. */ - deletedCount: number; - /** Number of documents upserted. */ - upsertedCount: number; - /** Inserted document generated Id's, hash key is the index of the originating operation */ - insertedIds: { [key: number]: ObjectId }; - /** Upserted document generated Id's, hash key is the index of the originating operation */ - upsertedIds: { [key: number]: ObjectId }; - /** Creates a new MongoBulkWriteError */ constructor(error: AnyError, result: BulkWriteResult) { super(error as Error); @@ -696,14 +682,35 @@ export class MongoBulkWriteError extends MongoError { this.name = 'MongoBulkWriteError'; this.result = result; + } - this.insertedCount = result.insertedCount; - this.matchedCount = result.matchedCount; - this.modifiedCount = result.modifiedCount; - this.deletedCount = result.deletedCount; - this.upsertedCount = result.upsertedCount; - this.insertedIds = result.insertedIds; - this.upsertedIds = result.upsertedIds; + /** Number of documents inserted. */ + get insertedCount(): number { + return this.result.insertedCount; + } + /** Number of documents matched for update. */ + get matchedCount(): number { + return this.result.matchedCount; + } + /** Number of documents modified. */ + get modifiedCount(): number { + return this.result.modifiedCount; + } + /** Number of documents deleted. */ + get deletedCount(): number { + return this.result.deletedCount; + } + /** Number of documents upserted. */ + get upsertedCount(): number { + return this.result.upsertedCount; + } + /** Inserted document generated Id's, hash key is the index of the originating operation */ + get insertedIds(): { [key: number]: any } { + return this.result.insertedIds; + } + /** Upserted document generated Id's, hash key is the index of the originating operation */ + get upsertedIds(): { [key: number]: any } { + return this.result.upsertedIds; } } diff --git a/test/functional/insert.test.js b/test/functional/insert.test.js index f9686feaa8..d5d83471cf 100644 --- a/test/functional/insert.test.js +++ b/test/functional/insert.test.js @@ -1,5 +1,5 @@ 'use strict'; -const { assert: test, withClient } = require('./shared'); +const { assert: test, withClient, ignoreNsNotFound } = require('./shared'); const { setupDatabase } = require('./shared'); const Script = require('vm'); const { expect } = require('chai'); @@ -15,7 +15,8 @@ const { Binary, MinKey, MaxKey, - Code + Code, + MongoBulkWriteError } = require('../../src'); /** @@ -2583,4 +2584,45 @@ describe('Insert', function () { }); } }); + + it('MongoBulkWriteError and BulkWriteResult should respect BulkWrite', function () { + const client = this.configuration.newClient(); + return client + .connect() + .then(() => { + return client.db().collection('test_insertMany_bulkResult').drop(); + }) + .catch(ignoreNsNotFound) + .then(() => { + const collection = client.db().collection('test_insertMany_bulkResult'); + return collection.insertMany( + [ + { _id: 2, x: 22 }, + { _id: 2, x: 22 }, + { _id: 3, x: 33 } + ], + { ordered: false } + ); + }) + .then(() => { + expect.fail('InsertMany should fail with multi key error'); + }) + .catch(error => { + expect(error).to.be.instanceOf(MongoBulkWriteError); + expect( + error.insertedCount, + 'MongoBulkWriteError.insertedCount did not respect BulkResult.nInserted' + ).to.equal(error.result.result.nInserted); + expect( + error.result.insertedCount, + 'BulkWriteResult.insertedCount did not respect BulkResult.nInserted' + ).to.equal(error.result.result.nInserted); + expect( + error.result.result.nInserted, + 'BulkWrite did not correctly represent the operation' + ).to.equal(2); + }) + .finally(() => client.db().collection('test_insertMany_bulkResult').drop()) + .finally(() => client.close()); + }); });