Skip to content
Prev Previous commit
Next Next commit
feat: add acknowledged to result
  • Loading branch information
durran committed Oct 14, 2024
commit 80a8b38d30adbbe14056351f49944678aeb935fe
8 changes: 6 additions & 2 deletions src/mongo_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,14 +491,18 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
async bulkWrite<SchemaMap extends Record<string, Document> = Record<string, Document>>(
models: ReadonlyArray<ClientBulkWriteModel<SchemaMap>>,
options?: ClientBulkWriteOptions
): Promise<ClientBulkWriteResult | { ok: 1 }> {
): Promise<ClientBulkWriteResult> {
if (this.autoEncrypter) {
throw new MongoInvalidArgumentError(
'MongoClient bulkWrite does not currently support automatic encryption.'
);
}
// We do not need schema type information past this point ("as any" is fine)
return await new ClientBulkWriteExecutor(this, models as any, options).execute();
return await new ClientBulkWriteExecutor(
this,
models as any,
resolveOptions(this, options)
).execute();
}

/**
Expand Down
4 changes: 4 additions & 0 deletions src/operations/client_bulk_write/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ export type ClientBulkWriteModel<

/** @public */
export interface ClientBulkWriteResult {
/**
* Whether the bulk write was acknowledged.
*/
acknowledged: boolean;
/**
* The total number of documents inserted across all insert operations.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/operations/client_bulk_write/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class ClientBulkWriteExecutor {
* for each, then merge the results into one.
* @returns The result.
*/
async execute(): Promise<ClientBulkWriteResult | { ok: 1 }> {
async execute(): Promise<ClientBulkWriteResult> {
// The command builder will take the user provided models and potential split the batch
// into multiple commands due to size.
const pkFactory = this.client.s.options.pkFactory;
Expand All @@ -92,7 +92,7 @@ export class ClientBulkWriteExecutor {
const operation = new ClientBulkWriteOperation(commandBuilder, this.options);
await executeOperation(this.client, operation);
}
return { ok: 1 };
return ClientBulkWriteResultsMerger.unacknowledged();
} else {
const resultsMerger = new ClientBulkWriteResultsMerger(this.options);
// For each command will will create and exhaust a cursor for the results.
Expand Down
23 changes: 23 additions & 0 deletions src/operations/client_bulk_write/results_merger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ import {
type ClientUpdateResult
} from './common';

/**
* Unacknowledged bulk writes are always the same.
*/
const UNACKNOWLEDGED = {
acknowledged: true,
insertedCount: 0,
upsertedCount: 0,
matchedCount: 0,
modifiedCount: 0,
deletedCount: 0,
insertResults: undefined,
updateResults: undefined,
deleteResults: undefined
};

/**
* Merges client bulk write cursor responses together into a single result.
* @internal
Expand All @@ -22,6 +37,13 @@ export class ClientBulkWriteResultsMerger {
writeConcernErrors: Document[];
writeErrors: Map<number, ClientBulkWriteError>;

/**
* @returns The standard unacknowledged bulk write result.
*/
static unacknowledged(): ClientBulkWriteResult {
return UNACKNOWLEDGED;
}

/**
* Instantiate the merger.
* @param options - The options.
Expand All @@ -32,6 +54,7 @@ export class ClientBulkWriteResultsMerger {
this.writeConcernErrors = [];
this.writeErrors = new Map();
this.result = {
acknowledged: true,
insertedCount: 0,
upsertedCount: 0,
matchedCount: 0,
Expand Down
59 changes: 30 additions & 29 deletions test/integration/crud/crud.prose.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
type AnyClientBulkWriteModel,
type ClientSession,
type Collection,
type Document,
MongoBulkWriteError,
type MongoClient,
MongoClientBulkWriteError,
Expand Down Expand Up @@ -175,7 +176,7 @@ describe('CRUD Prose Spec Tests', () => {
// firstEvent.operationId is equal to secondEvent.operationId.
let client: MongoClient;
let maxWriteBatchSize;
const models: AnyClientBulkWriteModel[] = [];
let models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand All @@ -188,12 +189,12 @@ describe('CRUD Prose Spec Tests', () => {
client.on('commandStarted', filterForCommands('bulkWrite', commands));
commands.length = 0;

Array.from({ length: maxWriteBatchSize + 1 }, () => {
models.push({
models = Array.from({ length: maxWriteBatchSize + 1 }, () => {
return {
namespace: 'db.coll',
name: 'insertOne',
document: { a: 'b' }
});
};
});
});

Expand Down Expand Up @@ -243,7 +244,7 @@ describe('CRUD Prose Spec Tests', () => {
let maxBsonObjectSize;
let maxMessageSizeBytes;
let numModels;
const models: AnyClientBulkWriteModel[] = [];
let models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand All @@ -258,14 +259,14 @@ describe('CRUD Prose Spec Tests', () => {
client.on('commandStarted', filterForCommands('bulkWrite', commands));
commands.length = 0;

Array.from({ length: numModels }, () => {
models.push({
models = Array.from({ length: numModels }, () => {
return {
name: 'insertOne',
namespace: 'db.coll',
document: {
a: 'b'.repeat(maxBsonObjectSize - 500)
}
});
};
});
});

Expand Down Expand Up @@ -314,7 +315,7 @@ describe('CRUD Prose Spec Tests', () => {
// Assert that two CommandStartedEvents were observed for the bulkWrite command.
let client: MongoClient;
let maxWriteBatchSize;
const models: AnyClientBulkWriteModel[] = [];
let models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand All @@ -338,12 +339,12 @@ describe('CRUD Prose Spec Tests', () => {
client.on('commandStarted', filterForCommands('bulkWrite', commands));
commands.length = 0;

Array.from({ length: maxWriteBatchSize + 1 }, () => {
models.push({
models = Array.from({ length: maxWriteBatchSize + 1 }, () => {
return {
namespace: 'db.coll',
name: 'insertOne',
document: { a: 'b' }
});
};
});
});

Expand Down Expand Up @@ -382,7 +383,7 @@ describe('CRUD Prose Spec Tests', () => {
// Construct a list of write models (referred to as models) with model repeated maxWriteBatchSize + 1 times.
let client: MongoClient;
let maxWriteBatchSize;
const models: AnyClientBulkWriteModel[] = [];
let models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand All @@ -396,12 +397,12 @@ describe('CRUD Prose Spec Tests', () => {
client.on('commandStarted', filterForCommands('bulkWrite', commands));
commands.length = 0;

Array.from({ length: maxWriteBatchSize + 1 }, () => {
models.push({
models = Array.from({ length: maxWriteBatchSize + 1 }, () => {
return {
namespace: 'db.coll',
name: 'insertOne',
document: { _id: 1 }
});
};
});
});

Expand Down Expand Up @@ -471,7 +472,7 @@ describe('CRUD Prose Spec Tests', () => {
// Assert that a CommandStartedEvent was observed for the getMore command.
let client: MongoClient;
let maxBsonObjectSize;
const models: AnyClientBulkWriteModel[] = [];
const models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand Down Expand Up @@ -545,7 +546,7 @@ describe('CRUD Prose Spec Tests', () => {
let client: MongoClient;
let session: ClientSession;
let maxBsonObjectSize;
const models: AnyClientBulkWriteModel[] = [];
const models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand Down Expand Up @@ -632,7 +633,7 @@ describe('CRUD Prose Spec Tests', () => {
// Assert that a CommandStartedEvent was observed for the killCursors command.
let client: MongoClient;
let maxBsonObjectSize;
const models: AnyClientBulkWriteModel[] = [];
const models: AnyClientBulkWriteModel<Document>[] = [];
const getMoreCommands: CommandStartedEvent[] = [];
const killCursorsCommands: CommandStartedEvent[] = [];

Expand Down Expand Up @@ -803,7 +804,7 @@ describe('CRUD Prose Spec Tests', () => {
let opsBytes;
let numModels;
let remainderBytes;
let models: AnyClientBulkWriteModel[] = [];
let models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand All @@ -821,12 +822,12 @@ describe('CRUD Prose Spec Tests', () => {
commands.length = 0;
models = [];

Array.from({ length: numModels }, () => {
models.push({
models = Array.from({ length: numModels }, () => {
return {
namespace: 'db.coll',
name: 'insertOne',
document: { a: 'b'.repeat(maxBsonObjectSize - 57) }
});
};
});

if (remainderBytes >= 217) {
Expand Down Expand Up @@ -859,7 +860,7 @@ describe('CRUD Prose Spec Tests', () => {
it('executes in a single batch', {
metadata: { requires: { mongodb: '>=8.0.0', serverless: 'forbid' } },
async test() {
const sameNamespaceModel: AnyClientBulkWriteModel = {
const sameNamespaceModel: AnyClientBulkWriteModel<Document> = {
name: 'insertOne',
namespace: 'db.coll',
document: { a: 'b' }
Expand Down Expand Up @@ -896,7 +897,7 @@ describe('CRUD Prose Spec Tests', () => {
metadata: { requires: { mongodb: '>=8.0.0', serverless: 'forbid' } },
async test() {
const namespace = `db.${'c'.repeat(200)}`;
const newNamespaceModel: AnyClientBulkWriteModel = {
const newNamespaceModel: AnyClientBulkWriteModel<Document> = {
name: 'insertOne',
namespace: namespace,
document: { a: 'b' }
Expand Down Expand Up @@ -950,7 +951,7 @@ describe('CRUD Prose Spec Tests', () => {
it('raises a client error', {
metadata: { requires: { mongodb: '>=8.0.0', serverless: 'forbid' } },
async test() {
const model: AnyClientBulkWriteModel = {
const model: AnyClientBulkWriteModel<Document> = {
name: 'insertOne',
namespace: 'db.coll',
document: { a: 'b'.repeat(maxMessageSizeBytes) }
Expand All @@ -976,7 +977,7 @@ describe('CRUD Prose Spec Tests', () => {
metadata: { requires: { mongodb: '>=8.0.0', serverless: 'forbid' } },
async test() {
const namespace = `db.${'c'.repeat(maxMessageSizeBytes)}`;
const model: AnyClientBulkWriteModel = {
const model: AnyClientBulkWriteModel<Document> = {
name: 'insertOne',
namespace: namespace,
document: { a: 'b' }
Expand Down Expand Up @@ -1033,7 +1034,7 @@ describe('CRUD Prose Spec Tests', () => {
});

it('raises a client side error', async function () {
const model: AnyClientBulkWriteModel = {
const model: AnyClientBulkWriteModel<Document> = {
name: 'insertOne',
namespace: 'db.coll',
document: { a: 'b' }
Expand Down Expand Up @@ -1113,7 +1114,7 @@ describe('CRUD Prose Spec Tests', () => {
let maxBsonObjectSize;
let maxMessageSizeBytes;
let numModels;
let models: AnyClientBulkWriteModel[] = [];
let models: AnyClientBulkWriteModel<Document>[] = [];
const commands: CommandStartedEvent[] = [];

beforeEach(async function () {
Expand Down