211 lines
7.7 KiB
JavaScript
211 lines
7.7 KiB
JavaScript
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.FindOperation = void 0;
|
||
|
const shared_1 = require("../cmap/wire_protocol/shared");
|
||
|
const error_1 = require("../error");
|
||
|
const read_concern_1 = require("../read_concern");
|
||
|
const sort_1 = require("../sort");
|
||
|
const utils_1 = require("../utils");
|
||
|
const command_1 = require("./command");
|
||
|
const operation_1 = require("./operation");
|
||
|
const SUPPORTS_WRITE_CONCERN_AND_COLLATION = 5;
|
||
|
/** @internal */
|
||
|
class FindOperation extends command_1.CommandOperation {
|
||
|
constructor(collection, ns, filter = {}, options = {}) {
|
||
|
super(collection, options);
|
||
|
this.options = options;
|
||
|
this.ns = ns;
|
||
|
if (typeof filter !== 'object' || Array.isArray(filter)) {
|
||
|
throw new error_1.MongoInvalidArgumentError('Query filter must be a plain object or ObjectId');
|
||
|
}
|
||
|
// If the filter is a buffer, validate that is a valid BSON document
|
||
|
if (Buffer.isBuffer(filter)) {
|
||
|
const objectSize = filter[0] | (filter[1] << 8) | (filter[2] << 16) | (filter[3] << 24);
|
||
|
if (objectSize !== filter.length) {
|
||
|
throw new error_1.MongoInvalidArgumentError(`Query filter raw message size does not match message header size [${filter.length}] != [${objectSize}]`);
|
||
|
}
|
||
|
}
|
||
|
// special case passing in an ObjectId as a filter
|
||
|
this.filter = filter != null && filter._bsontype === 'ObjectID' ? { _id: filter } : filter;
|
||
|
}
|
||
|
execute(server, session, callback) {
|
||
|
this.server = server;
|
||
|
const serverWireVersion = (0, utils_1.maxWireVersion)(server);
|
||
|
const options = this.options;
|
||
|
if (options.allowDiskUse != null && serverWireVersion < 4) {
|
||
|
callback(new error_1.MongoCompatibilityError('Option "allowDiskUse" is not supported on MongoDB < 3.2'));
|
||
|
return;
|
||
|
}
|
||
|
if (options.collation && serverWireVersion < SUPPORTS_WRITE_CONCERN_AND_COLLATION) {
|
||
|
callback(new error_1.MongoCompatibilityError(`Server ${server.name}, which reports wire version ${serverWireVersion}, does not support collation`));
|
||
|
return;
|
||
|
}
|
||
|
if (serverWireVersion < 4) {
|
||
|
if (this.readConcern && this.readConcern.level !== 'local') {
|
||
|
callback(new error_1.MongoCompatibilityError(`Server find command does not support a readConcern level of ${this.readConcern.level}`));
|
||
|
return;
|
||
|
}
|
||
|
const findCommand = makeLegacyFindCommand(this.ns, this.filter, options);
|
||
|
if ((0, shared_1.isSharded)(server) && this.readPreference) {
|
||
|
findCommand.$readPreference = this.readPreference.toJSON();
|
||
|
}
|
||
|
server.query(this.ns, findCommand, {
|
||
|
...this.options,
|
||
|
...this.bsonOptions,
|
||
|
documentsReturnedIn: 'firstBatch',
|
||
|
readPreference: this.readPreference
|
||
|
}, callback);
|
||
|
return;
|
||
|
}
|
||
|
let findCommand = makeFindCommand(this.ns, this.filter, options);
|
||
|
if (this.explain) {
|
||
|
findCommand = (0, utils_1.decorateWithExplain)(findCommand, this.explain);
|
||
|
}
|
||
|
server.command(this.ns, findCommand, {
|
||
|
...this.options,
|
||
|
...this.bsonOptions,
|
||
|
documentsReturnedIn: 'firstBatch',
|
||
|
session
|
||
|
}, callback);
|
||
|
}
|
||
|
}
|
||
|
exports.FindOperation = FindOperation;
|
||
|
function makeFindCommand(ns, filter, options) {
|
||
|
const findCommand = {
|
||
|
find: ns.collection,
|
||
|
filter
|
||
|
};
|
||
|
if (options.sort) {
|
||
|
findCommand.sort = (0, sort_1.formatSort)(options.sort);
|
||
|
}
|
||
|
if (options.projection) {
|
||
|
let projection = options.projection;
|
||
|
if (projection && Array.isArray(projection)) {
|
||
|
projection = projection.length
|
||
|
? projection.reduce((result, field) => {
|
||
|
result[field] = 1;
|
||
|
return result;
|
||
|
}, {})
|
||
|
: { _id: 1 };
|
||
|
}
|
||
|
findCommand.projection = projection;
|
||
|
}
|
||
|
if (options.hint) {
|
||
|
findCommand.hint = (0, utils_1.normalizeHintField)(options.hint);
|
||
|
}
|
||
|
if (typeof options.skip === 'number') {
|
||
|
findCommand.skip = options.skip;
|
||
|
}
|
||
|
if (typeof options.limit === 'number') {
|
||
|
if (options.limit < 0) {
|
||
|
findCommand.limit = -options.limit;
|
||
|
findCommand.singleBatch = true;
|
||
|
}
|
||
|
else {
|
||
|
findCommand.limit = options.limit;
|
||
|
}
|
||
|
}
|
||
|
if (typeof options.batchSize === 'number') {
|
||
|
if (options.batchSize < 0) {
|
||
|
if (options.limit &&
|
||
|
options.limit !== 0 &&
|
||
|
Math.abs(options.batchSize) < Math.abs(options.limit)) {
|
||
|
findCommand.limit = -options.batchSize;
|
||
|
}
|
||
|
findCommand.singleBatch = true;
|
||
|
}
|
||
|
else {
|
||
|
findCommand.batchSize = options.batchSize;
|
||
|
}
|
||
|
}
|
||
|
if (typeof options.singleBatch === 'boolean') {
|
||
|
findCommand.singleBatch = options.singleBatch;
|
||
|
}
|
||
|
if (options.comment) {
|
||
|
findCommand.comment = options.comment;
|
||
|
}
|
||
|
if (typeof options.maxTimeMS === 'number') {
|
||
|
findCommand.maxTimeMS = options.maxTimeMS;
|
||
|
}
|
||
|
const readConcern = read_concern_1.ReadConcern.fromOptions(options);
|
||
|
if (readConcern) {
|
||
|
findCommand.readConcern = readConcern.toJSON();
|
||
|
}
|
||
|
if (options.max) {
|
||
|
findCommand.max = options.max;
|
||
|
}
|
||
|
if (options.min) {
|
||
|
findCommand.min = options.min;
|
||
|
}
|
||
|
if (typeof options.returnKey === 'boolean') {
|
||
|
findCommand.returnKey = options.returnKey;
|
||
|
}
|
||
|
if (typeof options.showRecordId === 'boolean') {
|
||
|
findCommand.showRecordId = options.showRecordId;
|
||
|
}
|
||
|
if (typeof options.tailable === 'boolean') {
|
||
|
findCommand.tailable = options.tailable;
|
||
|
}
|
||
|
if (typeof options.timeout === 'boolean') {
|
||
|
findCommand.noCursorTimeout = !options.timeout;
|
||
|
}
|
||
|
else if (typeof options.noCursorTimeout === 'boolean') {
|
||
|
findCommand.noCursorTimeout = options.noCursorTimeout;
|
||
|
}
|
||
|
if (typeof options.awaitData === 'boolean') {
|
||
|
findCommand.awaitData = options.awaitData;
|
||
|
}
|
||
|
if (typeof options.allowPartialResults === 'boolean') {
|
||
|
findCommand.allowPartialResults = options.allowPartialResults;
|
||
|
}
|
||
|
if (options.collation) {
|
||
|
findCommand.collation = options.collation;
|
||
|
}
|
||
|
if (typeof options.allowDiskUse === 'boolean') {
|
||
|
findCommand.allowDiskUse = options.allowDiskUse;
|
||
|
}
|
||
|
if (options.let) {
|
||
|
findCommand.let = options.let;
|
||
|
}
|
||
|
return findCommand;
|
||
|
}
|
||
|
function makeLegacyFindCommand(ns, filter, options) {
|
||
|
const findCommand = {
|
||
|
$query: filter
|
||
|
};
|
||
|
if (options.sort) {
|
||
|
findCommand.$orderby = (0, sort_1.formatSort)(options.sort);
|
||
|
}
|
||
|
if (options.hint) {
|
||
|
findCommand.$hint = (0, utils_1.normalizeHintField)(options.hint);
|
||
|
}
|
||
|
if (typeof options.returnKey === 'boolean') {
|
||
|
findCommand.$returnKey = options.returnKey;
|
||
|
}
|
||
|
if (options.max) {
|
||
|
findCommand.$max = options.max;
|
||
|
}
|
||
|
if (options.min) {
|
||
|
findCommand.$min = options.min;
|
||
|
}
|
||
|
if (typeof options.showRecordId === 'boolean') {
|
||
|
findCommand.$showDiskLoc = options.showRecordId;
|
||
|
}
|
||
|
if (options.comment) {
|
||
|
findCommand.$comment = options.comment;
|
||
|
}
|
||
|
if (typeof options.maxTimeMS === 'number') {
|
||
|
findCommand.$maxTimeMS = options.maxTimeMS;
|
||
|
}
|
||
|
if (options.explain != null) {
|
||
|
findCommand.$explain = true;
|
||
|
}
|
||
|
return findCommand;
|
||
|
}
|
||
|
(0, operation_1.defineAspects)(FindOperation, [
|
||
|
operation_1.Aspect.READ_OPERATION,
|
||
|
operation_1.Aspect.RETRYABLE,
|
||
|
operation_1.Aspect.EXPLAINABLE,
|
||
|
operation_1.Aspect.CURSOR_CREATING
|
||
|
]);
|
||
|
//# sourceMappingURL=find.js.map
|