Skip to content

Commit b521d50

Browse files
committed
refactor: use functions not objects
1 parent 7985beb commit b521d50

File tree

2 files changed

+262
-443
lines changed

2 files changed

+262
-443
lines changed
Lines changed: 111 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { type Document } from '../../bson';
22
import { DocumentSequence } from '../../cmap/commands';
3-
import { MongoInvalidArgumentError } from '../../error';
43
import type {
54
AnyClientBulkWriteModel,
65
ClientBulkWriteOptions,
@@ -12,6 +11,17 @@ import type {
1211
ClientUpdateOneModel
1312
} from './common';
1413

14+
/** @internal */
15+
export interface ClientBulkWriteCommand {
16+
bulkWrite: 1;
17+
errorsOnly: boolean;
18+
ordered: boolean;
19+
ops: DocumentSequence;
20+
nsInfo: DocumentSequence;
21+
bypassDocumentValidation?: boolean;
22+
let?: Document;
23+
}
24+
1525
/** @internal */
1626
export class ClientBulkWriteCommandBuilder {
1727
models: AnyClientBulkWriteModel[];
@@ -40,123 +50,79 @@ export class ClientBulkWriteCommandBuilder {
4050
/**
4151
* Build the bulk write commands from the models.
4252
*/
43-
buildCommands(): Document[] {
44-
// The base command.
45-
const command: Document = {
46-
bulkWrite: 1,
47-
errorsOnly: this.errorsOnly,
48-
ordered: this.options.ordered ?? true
49-
};
50-
// Add bypassDocumentValidation if it was present in the options.
51-
if ('bypassDocumentValidation' in this.options) {
52-
command.bypassDocumentValidation = this.options.bypassDocumentValidation;
53-
}
54-
// Add let if it was present in the options.
55-
if ('let' in this.options) {
56-
command.let = this.options.let;
57-
}
58-
53+
buildCommands(): ClientBulkWriteCommand[] {
5954
// Iterate the models to build the ops and nsInfo fields.
6055
const operations = [];
6156
let currentNamespaceIndex = 0;
6257
const namespaces = new Map<string, number>();
6358
for (const model of this.models) {
6459
const ns = model.namespace;
6560
if (namespaces.has(ns)) {
66-
operations.push(builderFor(model).buildOperation(namespaces.get(ns) as number));
61+
operations.push(buildOperation(model, namespaces.get(ns) as number));
6762
} else {
6863
namespaces.set(ns, currentNamespaceIndex);
69-
operations.push(builderFor(model).buildOperation(currentNamespaceIndex));
64+
operations.push(buildOperation(model, currentNamespaceIndex));
7065
currentNamespaceIndex++;
7166
}
7267
}
7368

7469
const nsInfo = Array.from(namespaces.keys()).map(ns => {
7570
return { ns: ns };
7671
});
77-
command.ops = new DocumentSequence(operations);
78-
command.nsInfo = new DocumentSequence(nsInfo);
72+
73+
// The base command.
74+
const command: ClientBulkWriteCommand = {
75+
bulkWrite: 1,
76+
errorsOnly: this.errorsOnly,
77+
ordered: this.options.ordered ?? true,
78+
ops: new DocumentSequence(operations),
79+
nsInfo: new DocumentSequence(nsInfo)
80+
};
81+
// Add bypassDocumentValidation if it was present in the options.
82+
if ('bypassDocumentValidation' in this.options) {
83+
command.bypassDocumentValidation = this.options.bypassDocumentValidation;
84+
}
85+
// Add let if it was present in the options.
86+
if ('let' in this.options) {
87+
command.let = this.options.let;
88+
}
7989
return [command];
8090
}
8191
}
8292

83-
/** @internal */
84-
export interface OperationBuilder {
85-
buildOperation(index: number): Document;
86-
}
87-
8893
/**
89-
* Builds insert one operations given the model.
90-
* @internal
94+
* Build the insert one operation.
95+
* @param model - The insert one model.
96+
* @param index - The namespace index.
97+
* @returns the operation.
9198
*/
92-
export class InsertOneOperationBuilder implements OperationBuilder {
93-
model: ClientInsertOneModel;
94-
95-
/**
96-
* Instantiate the builder.
97-
* @param model - The client insert one model.
98-
*/
99-
constructor(model: ClientInsertOneModel) {
100-
this.model = model;
101-
}
102-
103-
/**
104-
* Build the operation.
105-
* @param index - The namespace index.
106-
* @returns the operation.
107-
*/
108-
buildOperation(index: number): Document {
109-
const document: Document = {
110-
insert: index,
111-
document: this.model.document
112-
};
113-
return document;
114-
}
115-
}
116-
117-
/** @internal */
118-
export class DeleteOneOperationBuilder implements OperationBuilder {
119-
model: ClientDeleteOneModel;
120-
121-
/**
122-
* Instantiate the builder.
123-
* @param model - The client delete one model.
124-
*/
125-
constructor(model: ClientDeleteOneModel) {
126-
this.model = model;
127-
}
128-
129-
/**
130-
* Build the operation.
131-
* @param index - The namespace index.
132-
* @returns the operation.
133-
*/
134-
buildOperation(index: number): Document {
135-
return createDeleteOperation(this.model, index, false);
136-
}
137-
}
138-
139-
/** @internal */
140-
export class DeleteManyOperationBuilder implements OperationBuilder {
141-
model: ClientDeleteManyModel;
99+
export const buildInsertOneOperation = (model: ClientInsertOneModel, index: number): Document => {
100+
const document: Document = {
101+
insert: index,
102+
document: model.document
103+
};
104+
return document;
105+
};
142106

143-
/**
144-
* Instantiate the builder.
145-
* @param model - The client delete many model.
146-
*/
147-
constructor(model: ClientDeleteManyModel) {
148-
this.model = model;
149-
}
107+
/**
108+
* Build the delete one operation.
109+
* @param model - The insert many model.
110+
* @param index - The namespace index.
111+
* @returns the operation.
112+
*/
113+
export const buildDeleteOneOperation = (model: ClientDeleteOneModel, index: number): Document => {
114+
return createDeleteOperation(model, index, false);
115+
};
150116

151-
/**
152-
* Build the operation.
153-
* @param index - The namespace index.
154-
* @returns the operation.
155-
*/
156-
buildOperation(index: number): Document {
157-
return createDeleteOperation(this.model, index, true);
158-
}
159-
}
117+
/**
118+
* Build the delete many operation.
119+
* @param model - The delete many model.
120+
* @param index - The namespace index.
121+
* @returns the operation.
122+
*/
123+
export const buildDeleteManyOperation = (model: ClientDeleteManyModel, index: number): Document => {
124+
return createDeleteOperation(model, index, true);
125+
};
160126

161127
/**
162128
* Creates a delete operation based on the parameters.
@@ -180,49 +146,25 @@ function createDeleteOperation(
180146
return document;
181147
}
182148

183-
/** @internal */
184-
export class UpdateOneOperationBuilder implements OperationBuilder {
185-
model: ClientUpdateOneModel;
186-
187-
/**
188-
* Instantiate the builder.
189-
* @param model - The client update one model.
190-
*/
191-
constructor(model: ClientUpdateOneModel) {
192-
this.model = model;
193-
}
194-
195-
/**
196-
* Build the operation.
197-
* @param index - The namespace index.
198-
* @returns the operation.
199-
*/
200-
buildOperation(index: number): Document {
201-
return createUpdateOperation(this.model, index, false);
202-
}
203-
}
204-
205-
/** @internal */
206-
export class UpdateManyOperationBuilder implements OperationBuilder {
207-
model: ClientUpdateManyModel;
208-
209-
/**
210-
* Instantiate the builder.
211-
* @param model - The client update many model.
212-
*/
213-
constructor(model: ClientUpdateManyModel) {
214-
this.model = model;
215-
}
149+
/**
150+
* Build the update one operation.
151+
* @param model - The update one model.
152+
* @param index - The namespace index.
153+
* @returns the operation.
154+
*/
155+
export const buildUpdateOneOperation = (model: ClientUpdateOneModel, index: number): Document => {
156+
return createUpdateOperation(model, index, false);
157+
};
216158

217-
/**
218-
* Build the operation.
219-
* @param index - The namespace index.
220-
* @returns the operation.
221-
*/
222-
buildOperation(index: number): Document {
223-
return createUpdateOperation(this.model, index, true);
224-
}
225-
}
159+
/**
160+
* Build the update many operation.
161+
* @param model - The update many model.
162+
* @param index - The namespace index.
163+
* @returns the operation.
164+
*/
165+
export const buildUpdateManyOperation = (model: ClientUpdateManyModel, index: number): Document => {
166+
return createUpdateOperation(model, index, true);
167+
};
226168

227169
/**
228170
* Creates a delete operation based on the parameters.
@@ -250,53 +192,42 @@ function createUpdateOperation(
250192
return document;
251193
}
252194

253-
/** @internal */
254-
export class ReplaceOneOperationBuilder implements OperationBuilder {
255-
model: ClientReplaceOneModel;
256-
257-
/**
258-
* Instantiate the builder.
259-
* @param model - The client replace one model.
260-
*/
261-
constructor(model: ClientReplaceOneModel) {
262-
this.model = model;
195+
/**
196+
* Build the replace one operation.
197+
* @param model - The replace one model.
198+
* @param index - The namespace index.
199+
* @returns the operation.
200+
*/
201+
export const buildReplaceOneOperation = (model: ClientReplaceOneModel, index: number): Document => {
202+
const document: Document = {
203+
update: index,
204+
multi: false,
205+
filter: model.filter,
206+
updateMods: model.replacement
207+
};
208+
if (model.hint) {
209+
document.hint = model.hint;
263210
}
264-
265-
/**
266-
* Build the operation.
267-
* @param index - The namespace index.
268-
* @returns the operation.
269-
*/
270-
buildOperation(index: number): Document {
271-
const document: Document = {
272-
update: index,
273-
multi: false,
274-
filter: this.model.filter,
275-
updateMods: this.model.replacement
276-
};
277-
if (this.model.hint) {
278-
document.hint = this.model.hint;
279-
}
280-
if (this.model.upsert) {
281-
document.upsert = this.model.upsert;
282-
}
283-
return document;
211+
if (model.upsert) {
212+
document.upsert = model.upsert;
284213
}
285-
}
286-
287-
const BUILDERS: Map<string, (model: AnyClientBulkWriteModel) => OperationBuilder> = new Map();
288-
BUILDERS.set('insertOne', model => new InsertOneOperationBuilder(model as ClientInsertOneModel));
289-
BUILDERS.set('deleteMany', model => new DeleteManyOperationBuilder(model as ClientDeleteManyModel));
290-
BUILDERS.set('deleteOne', model => new DeleteOneOperationBuilder(model as ClientDeleteOneModel));
291-
BUILDERS.set('updateMany', model => new UpdateManyOperationBuilder(model as ClientUpdateManyModel));
292-
BUILDERS.set('updateOne', model => new UpdateOneOperationBuilder(model as ClientUpdateOneModel));
293-
BUILDERS.set('replaceOne', model => new ReplaceOneOperationBuilder(model as ClientReplaceOneModel));
214+
return document;
215+
};
294216

295217
/** @internal */
296-
export function builderFor(model: AnyClientBulkWriteModel): OperationBuilder {
297-
const builder = BUILDERS.get(model.name)?.(model);
298-
if (!builder) {
299-
throw new MongoInvalidArgumentError(`Could not load builder for model ${model.name}`);
218+
export function buildOperation(model: AnyClientBulkWriteModel, index: number): Document {
219+
switch (model.name) {
220+
case 'insertOne':
221+
return buildInsertOneOperation(model, index);
222+
case 'deleteOne':
223+
return buildDeleteOneOperation(model, index);
224+
case 'deleteMany':
225+
return buildDeleteManyOperation(model, index);
226+
case 'updateOne':
227+
return buildUpdateOneOperation(model, index);
228+
case 'updateMany':
229+
return buildUpdateManyOperation(model, index);
230+
case 'replaceOne':
231+
return buildReplaceOneOperation(model, index);
300232
}
301-
return builder;
302233
}

0 commit comments

Comments
 (0)