Skip to content

Commit e628296

Browse files
refactor(NODE-7090): refactor remaining cursor operations to subclass ModernizedOperation (#4609)
1 parent 3d296b7 commit e628296

File tree

11 files changed

+189
-384
lines changed

11 files changed

+189
-384
lines changed

src/operations/find.ts

Lines changed: 28 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@ import type { Document } from '../bson';
22
import { CursorResponse, ExplainedCursorResponse } from '../cmap/wire_protocol/responses';
33
import { type AbstractCursorOptions, type CursorTimeoutMode } from '../cursor/abstract_cursor';
44
import { MongoInvalidArgumentError } from '../error';
5-
import {
6-
decorateWithExplain,
7-
type ExplainOptions,
8-
validateExplainTimeoutOptions
9-
} from '../explain';
10-
import { ReadConcern } from '../read_concern';
11-
import type { Server } from '../sdam/server';
12-
import type { ClientSession } from '../sessions';
5+
import { type ExplainOptions } from '../explain';
6+
import type { ServerCommandOptions } from '../sdam/server';
137
import { formatSort, type Sort } from '../sort';
148
import { type TimeoutContext } from '../timeout';
159
import { type MongoDBNamespace, normalizeHintField } from '../utils';
16-
import { type CollationOptions, CommandOperation, type CommandOperationOptions } from './command';
10+
import {
11+
type CollationOptions,
12+
type CommandOperationOptions,
13+
ModernizedCommandOperation
14+
} from './command';
1715
import { Aspect, defineAspects, type Hint } from './operation';
1816

1917
/**
@@ -92,7 +90,9 @@ export interface FindOneOptions extends FindOptions {
9290
}
9391

9492
/** @internal */
95-
export class FindOperation extends CommandOperation<CursorResponse> {
93+
export class FindOperation extends ModernizedCommandOperation<CursorResponse> {
94+
override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
95+
9696
/**
9797
* @remarks WriteConcern can still be present on the options because
9898
* we inherit options from the client/db/collection. The
@@ -116,39 +116,32 @@ export class FindOperation extends CommandOperation<CursorResponse> {
116116

117117
// special case passing in an ObjectId as a filter
118118
this.filter = filter != null && filter._bsontype === 'ObjectId' ? { _id: filter } : filter;
119+
120+
this.SERVER_COMMAND_RESPONSE_TYPE = this.explain ? ExplainedCursorResponse : CursorResponse;
119121
}
120122

121123
override get commandName() {
122124
return 'find' as const;
123125
}
124126

125-
override async execute(
126-
server: Server,
127-
session: ClientSession | undefined,
128-
timeoutContext: TimeoutContext
129-
): Promise<CursorResponse> {
130-
this.server = server;
131-
132-
const options = this.options;
127+
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
128+
return {
129+
...this.options,
130+
...this.bsonOptions,
131+
documentsReturnedIn: 'firstBatch',
132+
session: this.session,
133+
timeoutContext
134+
};
135+
}
133136

134-
let findCommand = makeFindCommand(this.ns, this.filter, options);
135-
if (this.explain) {
136-
validateExplainTimeoutOptions(this.options, this.explain);
137-
findCommand = decorateWithExplain(findCommand, this.explain);
138-
}
137+
override handleOk(
138+
response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
139+
): CursorResponse {
140+
return response;
141+
}
139142

140-
return await server.command(
141-
this.ns,
142-
findCommand,
143-
{
144-
...this.options,
145-
...this.bsonOptions,
146-
documentsReturnedIn: 'firstBatch',
147-
session,
148-
timeoutContext
149-
},
150-
this.explain ? ExplainedCursorResponse : CursorResponse
151-
);
143+
override buildCommandDocument(): Document {
144+
return makeFindCommand(this.ns, this.filter, this.options);
152145
}
153146
}
154147

@@ -217,15 +210,6 @@ function makeFindCommand(ns: MongoDBNamespace, filter: Document, options: FindOp
217210
findCommand.comment = options.comment;
218211
}
219212

220-
if (typeof options.maxTimeMS === 'number') {
221-
findCommand.maxTimeMS = options.maxTimeMS;
222-
}
223-
224-
const readConcern = ReadConcern.fromOptions(options);
225-
if (readConcern) {
226-
findCommand.readConcern = readConcern.toJSON();
227-
}
228-
229213
if (options.max) {
230214
findCommand.max = options.max;
231215
}
@@ -263,11 +247,6 @@ function makeFindCommand(ns: MongoDBNamespace, filter: Document, options: FindOp
263247
if (typeof options.allowPartialResults === 'boolean') {
264248
findCommand.allowPartialResults = options.allowPartialResults;
265249
}
266-
267-
if (options.collation) {
268-
findCommand.collation = options.collation;
269-
}
270-
271250
if (typeof options.allowDiskUse === 'boolean') {
272251
findCommand.allowDiskUse = options.allowDiskUse;
273252
}

src/operations/get_more.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { Long } from '../bson';
1+
import type { Document, Long } from '../bson';
2+
import { type Connection } from '../cmap/connection';
23
import { CursorResponse } from '../cmap/wire_protocol/responses';
34
import { MongoRuntimeError } from '../error';
4-
import type { Server } from '../sdam/server';
5-
import type { ClientSession } from '../sessions';
5+
import type { Server, ServerCommandOptions } from '../sdam/server';
66
import { type TimeoutContext } from '../timeout';
77
import { maxWireVersion, type MongoDBNamespace } from '../utils';
8-
import { AbstractOperation, Aspect, defineAspects, type OperationOptions } from './operation';
8+
import { Aspect, defineAspects, ModernizedOperation, type OperationOptions } from './operation';
99

1010
/** @internal */
1111
export interface GetMoreOptions extends OperationOptions {
@@ -37,7 +37,8 @@ export interface GetMoreCommand {
3737
}
3838

3939
/** @internal */
40-
export class GetMoreOperation extends AbstractOperation {
40+
export class GetMoreOperation extends ModernizedOperation<CursorResponse> {
41+
override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
4142
cursorId: Long;
4243
override options: GetMoreOptions;
4344

@@ -53,19 +54,8 @@ export class GetMoreOperation extends AbstractOperation {
5354
override get commandName() {
5455
return 'getMore' as const;
5556
}
56-
/**
57-
* Although there is a server already associated with the get more operation, the signature
58-
* for execute passes a server so we will just use that one.
59-
*/
60-
override async execute(
61-
server: Server,
62-
_session: ClientSession | undefined,
63-
timeoutContext: TimeoutContext
64-
): Promise<CursorResponse> {
65-
if (server !== this.server) {
66-
throw new MongoRuntimeError('Getmore must run on the same server operation began on');
67-
}
6857

58+
override buildCommand(connection: Connection): Document {
6959
if (this.cursorId == null || this.cursorId.isZero()) {
7060
throw new MongoRuntimeError('Unable to iterate cursor with no id');
7161
}
@@ -92,18 +82,26 @@ export class GetMoreOperation extends AbstractOperation {
9282

9383
// we check for undefined specifically here to allow falsy values
9484
// eslint-disable-next-line no-restricted-syntax
95-
if (this.options.comment !== undefined && maxWireVersion(server) >= 9) {
85+
if (this.options.comment !== undefined && maxWireVersion(connection) >= 9) {
9686
getMoreCmd.comment = this.options.comment;
9787
}
9888

99-
const commandOptions = {
89+
return getMoreCmd;
90+
}
91+
92+
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
93+
return {
10094
returnFieldSelector: null,
10195
documentsReturnedIn: 'nextBatch',
10296
timeoutContext,
10397
...this.options
10498
};
99+
}
105100

106-
return await server.command(this.ns, getMoreCmd, commandOptions, CursorResponse);
101+
override handleOk(
102+
response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
103+
): CursorResponse {
104+
return response;
107105
}
108106
}
109107

src/operations/indexes.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Document } from '../bson';
2+
import { type Connection } from '../cmap/connection';
23
import { CursorResponse } from '../cmap/wire_protocol/responses';
34
import type { Collection } from '../collection';
45
import { type AbstractCursorOptions } from '../cursor/abstract_cursor';
@@ -12,6 +13,7 @@ import {
1213
type CollationOptions,
1314
CommandOperation,
1415
type CommandOperationOptions,
16+
ModernizedCommandOperation,
1517
type OperationParent
1618
} from './command';
1719
import { Aspect, defineAspects } from './operation';
@@ -366,7 +368,8 @@ export type ListIndexesOptions = AbstractCursorOptions & {
366368
};
367369

368370
/** @internal */
369-
export class ListIndexesOperation extends CommandOperation<CursorResponse> {
371+
export class ListIndexesOperation extends ModernizedCommandOperation<CursorResponse> {
372+
override SERVER_COMMAND_RESPONSE_TYPE = CursorResponse;
370373
/**
371374
* @remarks WriteConcern can still be present on the options because
372375
* we inherit options from the client/db/collection. The
@@ -389,12 +392,8 @@ export class ListIndexesOperation extends CommandOperation<CursorResponse> {
389392
return 'listIndexes' as const;
390393
}
391394

392-
override async execute(
393-
server: Server,
394-
session: ClientSession | undefined,
395-
timeoutContext: TimeoutContext
396-
): Promise<CursorResponse> {
397-
const serverWireVersion = maxWireVersion(server);
395+
override buildCommandDocument(connection: Connection): Document {
396+
const serverWireVersion = maxWireVersion(connection);
398397

399398
const cursor = this.options.batchSize ? { batchSize: this.options.batchSize } : {};
400399

@@ -406,7 +405,13 @@ export class ListIndexesOperation extends CommandOperation<CursorResponse> {
406405
command.comment = this.options.comment;
407406
}
408407

409-
return await super.executeCommand(server, session, command, timeoutContext, CursorResponse);
408+
return command;
409+
}
410+
411+
override handleOk(
412+
response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
413+
): CursorResponse {
414+
return response;
410415
}
411416
}
412417

src/operations/kill_cursors.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import type { Long } from '../bson';
2-
import { MongoRuntimeError } from '../error';
3-
import type { Server } from '../sdam/server';
2+
import { type Connection } from '../cmap/connection';
3+
import { MongoDBResponse } from '../cmap/wire_protocol/responses';
4+
import { type MongoError, MongoRuntimeError } from '../error';
5+
import type { Server, ServerCommandOptions } from '../sdam/server';
46
import type { ClientSession } from '../sessions';
57
import { type TimeoutContext } from '../timeout';
6-
import { type MongoDBNamespace, squashError } from '../utils';
7-
import { AbstractOperation, Aspect, defineAspects, type OperationOptions } from './operation';
8+
import { type MongoDBNamespace } from '../utils';
9+
import { Aspect, defineAspects, ModernizedOperation, type OperationOptions } from './operation';
810

911
/**
1012
* https://www.mongodb.com/docs/manual/reference/command/killCursors/
@@ -16,7 +18,8 @@ interface KillCursorsCommand {
1618
comment?: unknown;
1719
}
1820

19-
export class KillCursorsOperation extends AbstractOperation {
21+
export class KillCursorsOperation extends ModernizedOperation<void> {
22+
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
2023
cursorId: Long;
2124

2225
constructor(cursorId: Long, ns: MongoDBNamespace, server: Server, options: OperationOptions) {
@@ -30,15 +33,7 @@ export class KillCursorsOperation extends AbstractOperation {
3033
return 'killCursors' as const;
3134
}
3235

33-
override async execute(
34-
server: Server,
35-
session: ClientSession | undefined,
36-
timeoutContext: TimeoutContext
37-
): Promise<void> {
38-
if (server !== this.server) {
39-
throw new MongoRuntimeError('Killcursor must run on the same server operation began on');
40-
}
41-
36+
override buildCommand(_connection: Connection, _session?: ClientSession): KillCursorsCommand {
4237
const killCursors = this.ns.collection;
4338
if (killCursors == null) {
4439
// Cursors should have adopted the namespace returned by MongoDB
@@ -50,15 +45,19 @@ export class KillCursorsOperation extends AbstractOperation {
5045
killCursors,
5146
cursors: [this.cursorId]
5247
};
53-
try {
54-
await server.command(this.ns, killCursorsCommand, {
55-
session,
56-
timeoutContext
57-
});
58-
} catch (error) {
59-
// The driver should never emit errors from killCursors, this is spec-ed behavior
60-
squashError(error);
61-
}
48+
49+
return killCursorsCommand;
50+
}
51+
52+
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
53+
return {
54+
session: this.session,
55+
timeoutContext
56+
};
57+
}
58+
59+
override handleError(_error: MongoError): void {
60+
// The driver should never emit errors from killCursors, this is spec-ed behavior
6261
}
6362
}
6463

0 commit comments

Comments
 (0)