Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/cmap/wire_protocol/constants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export const MIN_SUPPORTED_SERVER_VERSION = '4.2';
export const MAX_SUPPORTED_SERVER_VERSION = '8.0';
export const MAX_SUPPORTED_SERVER_VERSION = '8.2';
export const MIN_SUPPORTED_WIRE_VERSION = 8;
export const MAX_SUPPORTED_WIRE_VERSION = 25;
export const MAX_SUPPORTED_WIRE_VERSION = 27;
export const MIN_SUPPORTED_QE_WIRE_VERSION = 21;
export const MIN_SUPPORTED_QE_SERVER_VERSION = '7.0';
export const MIN_SUPPORTED_RAW_DATA_WIRE_VERSION = 27;
export const MIN_SUPPORTED_RAW_DATA_SERVER_VERSION = '8.2';
export const OP_REPLY = 1;
export const OP_UPDATE = 2001;
export const OP_INSERT = 2002;
Expand Down
3 changes: 2 additions & 1 deletion src/operations/aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,6 @@ defineAspects(AggregateOperation, [
Aspect.READ_OPERATION,
Aspect.RETRYABLE,
Aspect.EXPLAINABLE,
Aspect.CURSOR_CREATING
Aspect.CURSOR_CREATING,
Aspect.SUPPORTS_RAW_DATA
]);
3 changes: 2 additions & 1 deletion src/operations/client_bulk_write/client_bulk_write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ defineAspects(ClientBulkWriteOperation, [
Aspect.SKIP_COLLATION,
Aspect.CURSOR_CREATING,
Aspect.RETRYABLE,
Aspect.COMMAND_BATCHING
Aspect.COMMAND_BATCHING,
Aspect.SUPPORTS_RAW_DATA
]);
19 changes: 18 additions & 1 deletion src/operations/command.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type Connection } from '..';
import type { BSONSerializeOptions, Document } from '../bson';
import { MIN_SUPPORTED_RAW_DATA_WIRE_VERSION } from '../cmap/wire_protocol/constants';
import { MongoInvalidArgumentError } from '../error';
import {
decorateWithExplain,
Expand All @@ -12,7 +13,7 @@ import type { ReadPreference } from '../read_preference';
import type { ServerCommandOptions } from '../sdam/server';
import type { ClientSession } from '../sessions';
import { type TimeoutContext } from '../timeout';
import { commandSupportsReadConcern, MongoDBNamespace } from '../utils';
import { commandSupportsReadConcern, maxWireVersion, MongoDBNamespace } from '../utils';
import { WriteConcern, type WriteConcernOptions } from '../write_concern';
import type { ReadConcernLike } from './../read_concern';
import { AbstractOperation, Aspect, type OperationOptions } from './operation';
Expand Down Expand Up @@ -63,6 +64,14 @@ export interface CommandOperationOptions
* This option is deprecated and will be removed in an upcoming major version.
*/
noResponse?: boolean;

/**
* Used when the command needs to grant access to the underlying namespaces for time series collections.
* Only available on server versions 8.2 and above.
* @public
* @sinceServerVersion 8.2
**/
rawData?: boolean;
}

/** @internal */
Expand Down Expand Up @@ -153,6 +162,14 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
command.maxTimeMS = this.options.maxTimeMS;
}

if (
this.options.rawData != null &&
this.hasAspect(Aspect.SUPPORTS_RAW_DATA) &&
maxWireVersion(connection) >= MIN_SUPPORTED_RAW_DATA_WIRE_VERSION
) {
command.rawData = this.options.rawData;
}

if (this.hasAspect(Aspect.EXPLAINABLE) && this.explain) {
return decorateWithExplain(command, this.explain);
}
Expand Down
2 changes: 1 addition & 1 deletion src/operations/count.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ export class CountOperation extends CommandOperation<number> {
}
}

defineAspects(CountOperation, [Aspect.READ_OPERATION, Aspect.RETRYABLE]);
defineAspects(CountOperation, [Aspect.READ_OPERATION, Aspect.RETRYABLE, Aspect.SUPPORTS_RAW_DATA]);
2 changes: 1 addition & 1 deletion src/operations/create_collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export interface ClusteredCollectionOptions extends Document {
}

/** @public */
export interface CreateCollectionOptions extends CommandOperationOptions {
export interface CreateCollectionOptions extends Omit<CommandOperationOptions, 'rawData'> {
/** Create a capped collection */
capped?: boolean;
/** @deprecated Create an index on the _id field of the document. This option is deprecated in MongoDB 3.2+ and will be removed once no longer supported by the server. */
Expand Down
12 changes: 9 additions & 3 deletions src/operations/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,21 @@ export function makeDeleteStatement(
return op;
}

defineAspects(DeleteOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
defineAspects(DeleteOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(DeleteOneOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.EXPLAINABLE,
Aspect.SKIP_COLLATION
Aspect.SKIP_COLLATION,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(DeleteManyOperation, [
Aspect.WRITE_OPERATION,
Aspect.EXPLAINABLE,
Aspect.SKIP_COLLATION
Aspect.SKIP_COLLATION,
Aspect.SUPPORTS_RAW_DATA
]);
7 changes: 6 additions & 1 deletion src/operations/distinct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,9 @@ export class DistinctOperation extends CommandOperation<any[] | Document> {
}
}

defineAspects(DistinctOperation, [Aspect.READ_OPERATION, Aspect.RETRYABLE, Aspect.EXPLAINABLE]);
defineAspects(DistinctOperation, [
Aspect.READ_OPERATION,
Aspect.RETRYABLE,
Aspect.EXPLAINABLE,
Aspect.SUPPORTS_RAW_DATA
]);
2 changes: 1 addition & 1 deletion src/operations/drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { executeOperation } from './execute_operation';
import { Aspect, defineAspects } from './operation';

/** @public */
export interface DropCollectionOptions extends CommandOperationOptions {
export interface DropCollectionOptions extends Omit<CommandOperationOptions, 'rawData'> {
/** @experimental */
encryptedFields?: Document;
}
Expand Down
3 changes: 2 additions & 1 deletion src/operations/estimated_document_count.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ export class EstimatedDocumentCountOperation extends CommandOperation<number> {
defineAspects(EstimatedDocumentCountOperation, [
Aspect.READ_OPERATION,
Aspect.RETRYABLE,
Aspect.CURSOR_CREATING
Aspect.CURSOR_CREATING,
Aspect.SUPPORTS_RAW_DATA
]);
3 changes: 2 additions & 1 deletion src/operations/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,5 +258,6 @@ defineAspects(FindOperation, [
Aspect.READ_OPERATION,
Aspect.RETRYABLE,
Aspect.EXPLAINABLE,
Aspect.CURSOR_CREATING
Aspect.CURSOR_CREATING,
Aspect.SUPPORTS_RAW_DATA
]);
3 changes: 2 additions & 1 deletion src/operations/find_and_modify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,5 +314,6 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
defineAspects(FindAndModifyOperation, [
Aspect.WRITE_OPERATION,
Aspect.RETRYABLE,
Aspect.EXPLAINABLE
Aspect.EXPLAINABLE,
Aspect.SUPPORTS_RAW_DATA
]);
9 changes: 5 additions & 4 deletions src/operations/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ export class ListIndexesOperation extends CommandOperation<CursorResponse> {
* This allows typescript to delete the key but will
* not allow a writeConcern to be assigned as a property on options.
*/
override options: ListIndexesOptions & { writeConcern?: never };
override options: ListIndexesOptions & { writeConcern?: never; rawData?: boolean };
collectionNamespace: MongoDBNamespace;

constructor(collection: Collection, options?: ListIndexesOptions) {
Expand Down Expand Up @@ -409,7 +409,8 @@ export class ListIndexesOperation extends CommandOperation<CursorResponse> {
defineAspects(ListIndexesOperation, [
Aspect.READ_OPERATION,
Aspect.RETRYABLE,
Aspect.CURSOR_CREATING
Aspect.CURSOR_CREATING,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(CreateIndexesOperation, [Aspect.WRITE_OPERATION]);
defineAspects(DropIndexOperation, [Aspect.WRITE_OPERATION]);
defineAspects(CreateIndexesOperation, [Aspect.WRITE_OPERATION, Aspect.SUPPORTS_RAW_DATA]);
defineAspects(DropIndexOperation, [Aspect.WRITE_OPERATION, Aspect.SUPPORTS_RAW_DATA]);
12 changes: 10 additions & 2 deletions src/operations/insert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,13 @@ export interface InsertManyResult<TSchema = Document> {
insertedIds: { [key: number]: InferIdType<TSchema> };
}

defineAspects(InsertOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
defineAspects(InsertOneOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION]);
defineAspects(InsertOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(InsertOneOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.SUPPORTS_RAW_DATA
]);
3 changes: 2 additions & 1 deletion src/operations/list_collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,6 @@ export interface CollectionInfo extends Document {
defineAspects(ListCollectionsOperation, [
Aspect.READ_OPERATION,
Aspect.RETRYABLE,
Aspect.CURSOR_CREATING
Aspect.CURSOR_CREATING,
Aspect.SUPPORTS_RAW_DATA
]);
2 changes: 1 addition & 1 deletion src/operations/list_databases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface ListDatabasesResult {
}

/** @public */
export interface ListDatabasesOptions extends CommandOperationOptions {
export interface ListDatabasesOptions extends Omit<CommandOperationOptions, 'rawData'> {
/** A query predicate that determines which databases are listed */
filter?: Document;
/** A flag to indicate whether the command should return just the database names, or return both database names and size information */
Expand Down
3 changes: 2 additions & 1 deletion src/operations/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export const Aspect = {
SKIP_COLLATION: Symbol('SKIP_COLLATION'),
CURSOR_CREATING: Symbol('CURSOR_CREATING'),
MUST_SELECT_SAME_SERVER: Symbol('MUST_SELECT_SAME_SERVER'),
COMMAND_BATCHING: Symbol('COMMAND_BATCHING')
COMMAND_BATCHING: Symbol('COMMAND_BATCHING'),
SUPPORTS_RAW_DATA: Symbol('SUPPORTS_RAW_DATA')
} as const;

/** @public */
Expand Down
2 changes: 1 addition & 1 deletion src/operations/profiling_level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { MongoUnexpectedServerResponseError } from '../error';
import { CommandOperation, type CommandOperationOptions } from './command';

/** @public */
export type ProfilingLevelOptions = CommandOperationOptions;
export type ProfilingLevelOptions = Omit<CommandOperationOptions, 'rawData'>;

class ProfilingLevelResponse extends MongoDBResponse {
get was() {
Expand Down
2 changes: 1 addition & 1 deletion src/operations/remove_user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CommandOperation, type CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';

/** @public */
export type RemoveUserOptions = CommandOperationOptions;
export type RemoveUserOptions = Omit<CommandOperationOptions, 'rawData'>;

/** @internal */
export class RemoveUserOperation extends CommandOperation<boolean> {
Expand Down
2 changes: 1 addition & 1 deletion src/operations/rename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CommandOperation, type CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';

/** @public */
export interface RenameOptions extends CommandOperationOptions {
export interface RenameOptions extends Omit<CommandOperationOptions, 'rawData'> {
/** Drop the target name collection if it previously exists. */
dropTarget?: boolean;
/** Unclear */
Expand Down
2 changes: 1 addition & 1 deletion src/operations/set_profiling_level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const ProfilingLevel = Object.freeze({
export type ProfilingLevel = (typeof ProfilingLevel)[keyof typeof ProfilingLevel];

/** @public */
export type SetProfilingLevelOptions = CommandOperationOptions;
export type SetProfilingLevelOptions = Omit<CommandOperationOptions, 'rawData'>;

/** @internal */
export class SetProfilingLevelOperation extends CommandOperation<ProfilingLevel> {
Expand Down
2 changes: 1 addition & 1 deletion src/operations/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CommandOperation, type CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';

/** @public */
export interface DbStatsOptions extends CommandOperationOptions {
export interface DbStatsOptions extends Omit<CommandOperationOptions, 'rawData'> {
/** Divide the returned sizes by scale value. */
scale?: number;
}
Expand Down
16 changes: 12 additions & 4 deletions src/operations/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,20 +291,28 @@ export function makeUpdateStatement(
return op;
}

defineAspects(UpdateOperation, [Aspect.RETRYABLE, Aspect.WRITE_OPERATION, Aspect.SKIP_COLLATION]);
defineAspects(UpdateOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.SKIP_COLLATION,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(UpdateOneOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.EXPLAINABLE,
Aspect.SKIP_COLLATION
Aspect.SKIP_COLLATION,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(UpdateManyOperation, [
Aspect.WRITE_OPERATION,
Aspect.EXPLAINABLE,
Aspect.SKIP_COLLATION
Aspect.SKIP_COLLATION,
Aspect.SUPPORTS_RAW_DATA
]);
defineAspects(ReplaceOneOperation, [
Aspect.RETRYABLE,
Aspect.WRITE_OPERATION,
Aspect.SKIP_COLLATION
Aspect.SKIP_COLLATION,
Aspect.SUPPORTS_RAW_DATA
]);
2 changes: 1 addition & 1 deletion src/operations/validate_collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { ClientSession } from '../sessions';
import { CommandOperation, type CommandOperationOptions } from './command';

/** @public */
export interface ValidateCollectionOptions extends CommandOperationOptions {
export interface ValidateCollectionOptions extends Omit<CommandOperationOptions, 'rawData'> {
/** Validates a collection in the background, without interrupting read or write traffic (only in MongoDB 4.4+) */
background?: boolean;
}
Expand Down
40 changes: 23 additions & 17 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,34 +359,40 @@ export function uuidV4(): Buffer {
* A helper function for determining `maxWireVersion` between legacy and new topology instances
* @internal
*/
export function maxWireVersion(topologyOrServer?: Connection | Topology | Server): number {
if (topologyOrServer) {
if (topologyOrServer.loadBalanced || topologyOrServer.serverApi?.version) {
// Since we do not have a monitor in the load balanced mode,
// we assume the load-balanced server is always pointed at the latest mongodb version.
// There is a risk that for on-prem deployments
// that don't upgrade immediately that this could alert to the
// application that a feature is available that is actually not.
// We also return the max supported wire version for serverAPI.
export function maxWireVersion(handshakeAware?: Connection | Topology | Server): number {
if (handshakeAware) {
if (handshakeAware.hello) {
return handshakeAware.hello.maxWireVersion;
}

if (handshakeAware.serverApi?.version) {
// We return the max supported wire version for serverAPI.
return MAX_SUPPORTED_WIRE_VERSION;
}
if (topologyOrServer.hello) {
return topologyOrServer.hello.maxWireVersion;
// This is the fallback case for load balanced mode. If we are building commands the
// object being checked will be a connection, and we will have a hello response on
// it. For other cases, such as retryable writes, the object will be a server or
// topology, and there will be no hello response on those objects, so we return
// the max wire version so we support retryability. Once we have a min supported
// wire version of 9, then the needsRetryableWriteLabel() check can remove the
// usage of passing the wire version into it.
if (handshakeAware.loadBalanced) {
return MAX_SUPPORTED_WIRE_VERSION;
}

if ('lastHello' in topologyOrServer && typeof topologyOrServer.lastHello === 'function') {
const lastHello = topologyOrServer.lastHello();
if ('lastHello' in handshakeAware && typeof handshakeAware.lastHello === 'function') {
const lastHello = handshakeAware.lastHello();
if (lastHello) {
return lastHello.maxWireVersion;
}
}

if (
topologyOrServer.description &&
'maxWireVersion' in topologyOrServer.description &&
topologyOrServer.description.maxWireVersion != null
handshakeAware.description &&
'maxWireVersion' in handshakeAware.description &&
handshakeAware.description.maxWireVersion != null
) {
return topologyOrServer.description.maxWireVersion;
return handshakeAware.description.maxWireVersion;
}
}

Expand Down
Loading