mongodb 6.18.0-dev.20250801.sha.aac76296 → 6.18.0-dev.20250805.sha.ff9a7858

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,17 @@
1
+ import { type Connection, type MongoError } from '../..';
1
2
  import type { Document } from '../../bson';
3
+ import { MongoDBResponse } from '../../cmap/wire_protocol/responses';
2
4
  import type { Collection } from '../../collection';
3
5
  import { MONGODB_ERROR_CODES, MongoServerError } from '../../error';
4
- import type { Server } from '../../sdam/server';
6
+ import type { ServerCommandOptions } from '../../sdam/server';
5
7
  import type { ClientSession } from '../../sessions';
6
8
  import { type TimeoutContext } from '../../timeout';
7
- import { AbstractOperation } from '../operation';
9
+ import { ModernizedOperation } from '../operation';
8
10
 
9
11
  /** @internal */
10
- export class DropSearchIndexOperation extends AbstractOperation<void> {
12
+ export class DropSearchIndexOperation extends ModernizedOperation<void> {
13
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
14
+
11
15
  private readonly collection: Collection;
12
16
  private readonly name: string;
13
17
 
@@ -15,17 +19,14 @@ export class DropSearchIndexOperation extends AbstractOperation<void> {
15
19
  super();
16
20
  this.collection = collection;
17
21
  this.name = name;
22
+ this.ns = collection.fullNamespace;
18
23
  }
19
24
 
20
25
  override get commandName() {
21
26
  return 'dropSearchIndex' as const;
22
27
  }
23
28
 
24
- override async execute(
25
- server: Server,
26
- session: ClientSession | undefined,
27
- timeoutContext: TimeoutContext
28
- ): Promise<void> {
29
+ override buildCommand(_connection: Connection, _session?: ClientSession): Document {
29
30
  const namespace = this.collection.fullNamespace;
30
31
 
31
32
  const command: Document = {
@@ -36,14 +37,22 @@ export class DropSearchIndexOperation extends AbstractOperation<void> {
36
37
  command.name = this.name;
37
38
  }
38
39
 
39
- try {
40
- await server.command(namespace, command, { session, timeoutContext });
41
- } catch (error) {
42
- const isNamespaceNotFoundError =
43
- error instanceof MongoServerError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound;
44
- if (!isNamespaceNotFoundError) {
45
- throw error;
46
- }
40
+ return command;
41
+ }
42
+
43
+ override handleOk(_response: MongoDBResponse): void {
44
+ // do nothing
45
+ }
46
+
47
+ override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
48
+ return { session: this.session, timeoutContext };
49
+ }
50
+
51
+ override handleError(error: MongoError): void {
52
+ const isNamespaceNotFoundError =
53
+ error instanceof MongoServerError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound;
54
+ if (!isNamespaceNotFoundError) {
55
+ throw error;
47
56
  }
48
57
  }
49
58
  }
@@ -38,6 +38,7 @@ import {
38
38
  import type { ServerApi } from '../mongo_client';
39
39
  import { type Abortable, TypedEventEmitter } from '../mongo_types';
40
40
  import type { GetMoreOptions } from '../operations/get_more';
41
+ import { type ModernizedOperation } from '../operations/operation';
41
42
  import type { ClientSession } from '../sessions';
42
43
  import { type TimeoutContext } from '../timeout';
43
44
  import { isTransactionCommand } from '../transactions';
@@ -277,6 +278,100 @@ export class Server extends TypedEventEmitter<ServerEvents> {
277
278
  }
278
279
  }
279
280
 
281
+ public async modernCommand<TResult>(
282
+ operation: ModernizedOperation<TResult>,
283
+ timeoutContext: TimeoutContext
284
+ ): Promise<InstanceType<typeof operation.SERVER_COMMAND_RESPONSE_TYPE>> {
285
+ if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {
286
+ throw new MongoServerClosedError();
287
+ }
288
+ const session = operation.session;
289
+
290
+ let conn = session?.pinnedConnection;
291
+
292
+ this.incrementOperationCount();
293
+ if (conn == null) {
294
+ try {
295
+ conn = await this.pool.checkOut({ timeoutContext });
296
+ } catch (checkoutError) {
297
+ this.decrementOperationCount();
298
+ if (!(checkoutError instanceof PoolClearedError)) this.handleError(checkoutError);
299
+ throw checkoutError;
300
+ }
301
+ }
302
+
303
+ const cmd = operation.buildCommand(conn, session);
304
+ const options = operation.buildOptions(timeoutContext);
305
+ const ns = operation.ns;
306
+
307
+ if (this.loadBalanced && isPinnableCommand(cmd, session) && !session?.pinnedConnection) {
308
+ session?.pin(conn);
309
+ }
310
+
311
+ options.directConnection = this.topology.s.options.directConnection;
312
+
313
+ // There are cases where we need to flag the read preference not to get sent in
314
+ // the command, such as pre-5.0 servers attempting to perform an aggregate write
315
+ // with a non-primary read preference. In this case the effective read preference
316
+ // (primary) is not the same as the provided and must be removed completely.
317
+ if (options.omitReadPreference) {
318
+ delete options.readPreference;
319
+ }
320
+
321
+ if (this.description.iscryptd) {
322
+ options.omitMaxTimeMS = true;
323
+ }
324
+
325
+ let reauthPromise: Promise<void> | null = null;
326
+
327
+ try {
328
+ try {
329
+ const res = await conn.command(ns, cmd, options, operation.SERVER_COMMAND_RESPONSE_TYPE);
330
+ throwIfWriteConcernError(res);
331
+ return res;
332
+ } catch (commandError) {
333
+ throw this.decorateCommandError(conn, cmd, options, commandError);
334
+ }
335
+ } catch (operationError) {
336
+ if (
337
+ operationError instanceof MongoError &&
338
+ operationError.code === MONGODB_ERROR_CODES.Reauthenticate
339
+ ) {
340
+ reauthPromise = this.pool.reauthenticate(conn);
341
+ reauthPromise.then(undefined, error => {
342
+ reauthPromise = null;
343
+ squashError(error);
344
+ });
345
+
346
+ await abortable(reauthPromise, options);
347
+ reauthPromise = null; // only reachable if reauth succeeds
348
+
349
+ try {
350
+ const res = await conn.command(ns, cmd, options, operation.SERVER_COMMAND_RESPONSE_TYPE);
351
+ throwIfWriteConcernError(res);
352
+ return res;
353
+ } catch (commandError) {
354
+ throw this.decorateCommandError(conn, cmd, options, commandError);
355
+ }
356
+ } else {
357
+ throw operationError;
358
+ }
359
+ } finally {
360
+ this.decrementOperationCount();
361
+ if (session?.pinnedConnection !== conn) {
362
+ if (reauthPromise != null) {
363
+ // The reauth promise only exists if it hasn't thrown.
364
+ const checkBackIn = () => {
365
+ this.pool.checkIn(conn);
366
+ };
367
+ void reauthPromise.then(checkBackIn, checkBackIn);
368
+ } else {
369
+ this.pool.checkIn(conn);
370
+ }
371
+ }
372
+ }
373
+ }
374
+
280
375
  public async command<T extends MongoDBResponseConstructor>(
281
376
  ns: MongoDBNamespace,
282
377
  command: Document,