From ef423ff3245eb006e917ddfa4cbdba7a91d3560d Mon Sep 17 00:00:00 2001 From: Andy Mina Date: Mon, 14 Jun 2021 20:23:24 -0400 Subject: [PATCH] fix(NODE-3150): added bsonRegExp option for v3.6 --- lib/cmap/connection.js | 1 + lib/collection.js | 9 +++ lib/core/connection/commands.js | 13 +++- lib/core/connection/connection.js | 5 +- lib/core/connection/msg.js | 13 +++- lib/core/connection/pool.js | 4 + lib/core/cursor.js | 7 ++ lib/core/sdam/monitor.js | 3 +- lib/core/sdam/server.js | 1 + lib/core/topologies/mongos.js | 1 + lib/core/topologies/replset.js | 1 + lib/core/topologies/server.js | 2 + lib/core/wireprotocol/shared.js | 1 + lib/db.js | 7 +- lib/mongo_client.js | 1 + lib/operations/command.js | 1 + lib/operations/connect.js | 1 + lib/operations/db_ops.js | 1 + lib/topologies/mongos.js | 1 + lib/topologies/replset.js | 1 + lib/topologies/server.js | 1 + .../unified-spec-runner/operations.ts | 2 + test/unit/bson_regex.test.js | 74 +++++++++++++++++++ 23 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 test/unit/bson_regex.test.js diff --git a/lib/cmap/connection.js b/lib/cmap/connection.js index 81925b9621..f8aad15dd1 100644 --- a/lib/cmap/connection.js +++ b/lib/cmap/connection.js @@ -317,6 +317,7 @@ function write(command, options, callback) { promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true, promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true, promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false, + bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false, raw: typeof options.raw === 'boolean' ? options.raw : false }; diff --git a/lib/collection.js b/lib/collection.js index 09b8304b68..d55b242610 100644 --- a/lib/collection.js +++ b/lib/collection.js @@ -120,6 +120,8 @@ function Collection(db, topology, dbName, name, pkFactory, options) { options == null || options.promoteBuffers == null ? db.s.options.promoteBuffers : options.promoteBuffers; + const bsonRegExp = + options == null || options.bsonRegExp == null ? db.s.options.bsonRegExp : options.bsonRegExp; const collectionHint = null; const namespace = new MongoDBNamespace(dbName, name); @@ -156,6 +158,8 @@ function Collection(db, topology, dbName, name, pkFactory, options) { promoteValues: promoteValues, // promoteBuffers promoteBuffers: promoteBuffers, + // bsonRegExp + bsonRegExp: bsonRegExp, // internalHint internalHint: internalHint, // collectionHint @@ -303,6 +307,7 @@ const DEPRECATED_FIND_OPTIONS = ['maxScan', 'fields', 'snapshot', 'oplogReplay'] * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution. * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {boolean} [options.partial=false] Specify if the cursor should return partial results when querying against a sharded system * @param {number} [options.maxTimeMS] Number of milliseconds to wait before aborting the query. @@ -451,6 +456,8 @@ Collection.prototype.find = deprecateOptions( newOptions.promoteValues = this.s.promoteValues; if (newOptions.promoteBuffers == null && typeof this.s.promoteBuffers === 'boolean') newOptions.promoteBuffers = this.s.promoteBuffers; + if (newOptions.bsonRegExp == null && typeof this.s.bsonRegExp === 'boolean') + newOptions.bsonRegExp = this.s.bsonRegExp; // Sort options if (findCommand.sort) { @@ -1075,6 +1082,7 @@ Collection.prototype.save = deprecate(function(doc, options, callback) { * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution. * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {boolean} [options.partial=false] Specify if the cursor should return partial results when querying against a sharded system * @param {number} [options.maxTimeMS] Number of milliseconds to wait before aborting the query. @@ -1899,6 +1907,7 @@ Collection.prototype.findAndRemove = deprecate(function(query, sort, options, ca * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution. * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {object} [options.collation] Specify collation settings for operation. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}. * @param {string} [options.comment] Add a comment to an aggregation command * @param {string|object} [options.hint] Add an index selection hint to an aggregation command diff --git a/lib/core/connection/commands.js b/lib/core/connection/commands.js index b24ff8481c..b5446d9351 100644 --- a/lib/core/connection/commands.js +++ b/lib/core/connection/commands.js @@ -398,7 +398,12 @@ KillCursor.prototype.toBin = function() { }; var Response = function(bson, message, msgHeader, msgBody, opts) { - opts = opts || { promoteLongs: true, promoteValues: true, promoteBuffers: false }; + opts = opts || { + promoteLongs: true, + promoteValues: true, + promoteBuffers: false, + bsonRegExp: false + }; this.parsed = false; this.raw = message; this.data = msgBody; @@ -429,6 +434,7 @@ var Response = function(bson, message, msgHeader, msgBody, opts) { this.promoteLongs = typeof opts.promoteLongs === 'boolean' ? opts.promoteLongs : true; this.promoteValues = typeof opts.promoteValues === 'boolean' ? opts.promoteValues : true; this.promoteBuffers = typeof opts.promoteBuffers === 'boolean' ? opts.promoteBuffers : false; + this.bsonRegExp = typeof opts.bsonRegExp === 'boolean' ? opts.bsonRegExp : false; }; Response.prototype.isParsed = function() { @@ -449,13 +455,16 @@ Response.prototype.parse = function(options) { typeof options.promoteValues === 'boolean' ? options.promoteValues : this.opts.promoteValues; var promoteBuffers = typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : this.opts.promoteBuffers; + var bsonRegExp = + typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : this.opts.bsonRegExp; var bsonSize, _options; // Set up the options _options = { promoteLongs: promoteLongs, promoteValues: promoteValues, - promoteBuffers: promoteBuffers + promoteBuffers: promoteBuffers, + bsonRegExp: bsonRegExp }; // Position within OP_REPLY at which documents start diff --git a/lib/core/connection/connection.js b/lib/core/connection/connection.js index 5b22513b2a..ae36e0f778 100644 --- a/lib/core/connection/connection.js +++ b/lib/core/connection/connection.js @@ -38,6 +38,7 @@ const DEBUG_FIELDS = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'checkServerIdentity' ]; @@ -73,6 +74,7 @@ class Connection extends EventEmitter { * @param {boolean} [options.promoteLongs] Convert Long values from the db into Numbers if they fit into 53 bits * @param {boolean} [options.promoteValues] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {number} [options.maxBsonMessageSize=0x4000000] Largest possible size of a BSON message (for legacy purposes) */ constructor(socket, options) { @@ -117,7 +119,8 @@ class Connection extends EventEmitter { this.responseOptions = { promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true, promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true, - promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false + promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false, + bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false }; // Flushing diff --git a/lib/core/connection/msg.js b/lib/core/connection/msg.js index e241c096af..49744c328e 100644 --- a/lib/core/connection/msg.js +++ b/lib/core/connection/msg.js @@ -139,7 +139,12 @@ Msg.getRequestId = function() { class BinMsg { constructor(bson, message, msgHeader, msgBody, opts) { - opts = opts || { promoteLongs: true, promoteValues: true, promoteBuffers: false }; + opts = opts || { + promoteLongs: true, + promoteValues: true, + promoteBuffers: false, + bsonRegExp: false + }; this.parsed = false; this.raw = message; this.data = msgBody; @@ -161,6 +166,7 @@ class BinMsg { this.promoteLongs = typeof opts.promoteLongs === 'boolean' ? opts.promoteLongs : true; this.promoteValues = typeof opts.promoteValues === 'boolean' ? opts.promoteValues : true; this.promoteBuffers = typeof opts.promoteBuffers === 'boolean' ? opts.promoteBuffers : false; + this.bsonRegExp = typeof opts.bsonRegExp === 'boolean' ? opts.bsonRegExp : false; this.documents = []; } @@ -186,12 +192,15 @@ class BinMsg { typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : this.opts.promoteBuffers; + const bsonRegExp = + typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : this.opts.bsonRegExp; // Set up the options const _options = { promoteLongs: promoteLongs, promoteValues: promoteValues, - promoteBuffers: promoteBuffers + promoteBuffers: promoteBuffers, + bsonRegExp: bsonRegExp }; while (this.index < this.data.length) { diff --git a/lib/core/connection/pool.js b/lib/core/connection/pool.js index f0061ee914..a0cd25cabc 100644 --- a/lib/core/connection/pool.js +++ b/lib/core/connection/pool.js @@ -76,6 +76,7 @@ var _id = 0; * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. * @fires Pool#connect * @fires Pool#close @@ -127,6 +128,7 @@ var Pool = function(topology, options) { promoteLongs: true, promoteValues: true, promoteBuffers: false, + bsonRegExp: false, // Reconnection options reconnect: true, reconnectInterval: 1000, @@ -870,6 +872,7 @@ Pool.prototype.write = function(command, options, cb) { promoteLongs: true, promoteValues: true, promoteBuffers: false, + bsonRegExp: false, fullResult: false }; @@ -879,6 +882,7 @@ Pool.prototype.write = function(command, options, cb) { typeof options.promoteValues === 'boolean' ? options.promoteValues : true; operation.promoteBuffers = typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false; + operation.bsonRegExp = typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false; operation.raw = typeof options.raw === 'boolean' ? options.raw : false; operation.immediateRelease = typeof options.immediateRelease === 'boolean' ? options.immediateRelease : false; diff --git a/lib/core/cursor.js b/lib/core/cursor.js index 48b60d1a95..7282a6b139 100644 --- a/lib/core/cursor.js +++ b/lib/core/cursor.js @@ -146,6 +146,13 @@ class CoreCursor extends Readable { this.cursorState.promoteBuffers = options.promoteBuffers; } + // Add bsonRegExp to cursor state + if (typeof topologyOptions.bsonRegExp === 'boolean') { + this.cursorState.bsonRegExp = topologyOptions.bsonRegExp; + } else if (typeof options.bsonRegExp === 'boolean') { + this.cursorState.bsonRegExp = options.bsonRegExp; + } + if (topologyOptions.reconnect) { this.cursorState.reconnect = topologyOptions.reconnect; } diff --git a/lib/core/sdam/monitor.js b/lib/core/sdam/monitor.js index 701fb59b28..8a0876b746 100644 --- a/lib/core/sdam/monitor.js +++ b/lib/core/sdam/monitor.js @@ -85,7 +85,8 @@ class Monitor extends EventEmitter { raw: false, promoteLongs: true, promoteValues: true, - promoteBuffers: true + promoteBuffers: true, + bsonRegExp: true } ); diff --git a/lib/core/sdam/server.js b/lib/core/sdam/server.js index 26aeb5ed23..379d2ccd6f 100644 --- a/lib/core/sdam/server.js +++ b/lib/core/sdam/server.js @@ -49,6 +49,7 @@ const DEBUG_FIELDS = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'servername' ]; diff --git a/lib/core/topologies/mongos.js b/lib/core/topologies/mongos.js index b07d14ec69..27eb237596 100644 --- a/lib/core/topologies/mongos.js +++ b/lib/core/topologies/mongos.js @@ -88,6 +88,7 @@ var handlers = ['connect', 'close', 'error', 'timeout', 'parseError']; * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. * @param {boolean} [options.monitorCommands=false] Enable command monitoring for this topology * @return {Mongos} A cursor instance diff --git a/lib/core/topologies/replset.js b/lib/core/topologies/replset.js index 03adc7cfe6..02c2148683 100644 --- a/lib/core/topologies/replset.js +++ b/lib/core/topologies/replset.js @@ -88,6 +88,7 @@ var handlers = ['connect', 'close', 'error', 'timeout', 'parseError']; * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {number} [options.pingInterval=5000] Ping interval to check the response time to the different servers * @param {number} [options.localThresholdMS=15] Cutoff latency point in MS for Replicaset member selection * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. diff --git a/lib/core/topologies/server.js b/lib/core/topologies/server.js index c6a0bfa5db..275b8dbaa5 100644 --- a/lib/core/topologies/server.js +++ b/lib/core/topologies/server.js @@ -46,6 +46,7 @@ var debugFields = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'servername' ]; @@ -88,6 +89,7 @@ function topologyId(server) { * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {string} [options.appname=null] Application name, passed in on ismaster call and logged in mongod server logs. Maximum size 128 bytes. * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. * @param {boolean} [options.monitorCommands=false] Enable command monitoring for this topology diff --git a/lib/core/wireprotocol/shared.js b/lib/core/wireprotocol/shared.js index c586f05754..99c70a398e 100644 --- a/lib/core/wireprotocol/shared.js +++ b/lib/core/wireprotocol/shared.js @@ -57,6 +57,7 @@ function applyCommonQueryOptions(queryOptions, options) { promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true, promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true, promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false, + bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false, monitoring: typeof options.monitoring === 'boolean' ? options.monitoring : false, fullResult: typeof options.fullResult === 'boolean' ? options.fullResult : false }); diff --git a/lib/db.js b/lib/db.js index eb70fa6d80..4d97ab8729 100644 --- a/lib/db.js +++ b/lib/db.js @@ -83,7 +83,6 @@ const legalOptionNames = [ 'bufferMaxEntries', 'authSource', 'ignoreUndefined', - 'promoteLongs', 'promiseLibrary', 'readConcern', 'retryMiliSeconds', @@ -95,6 +94,7 @@ const legalOptionNames = [ 'promoteBuffers', 'promoteLongs', 'promoteValues', + 'bsonRegExp', 'compression', 'retryWrites' ]; @@ -117,6 +117,7 @@ const legalOptionNames = [ * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited. * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys. @@ -323,6 +324,7 @@ Db.prototype.command = function(command, options, callback) { * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution. * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types. * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers. + * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields). * @param {string} [options.comment] Add a comment to an aggregation command * @param {string|object} [options.hint] Add an index selection hint to an aggregation command @@ -391,7 +393,8 @@ const COLLECTION_OPTION_KEYS = [ 'ignoreUndefined', 'promoteValues', 'promoteBuffers', - 'promoteLongs' + 'promoteLongs', + 'bsonRegExp' ]; /** diff --git a/lib/mongo_client.js b/lib/mongo_client.js index 7e11512bf1..5e668a681e 100644 --- a/lib/mongo_client.js +++ b/lib/mongo_client.js @@ -144,6 +144,7 @@ const validOptions = require('./operations/connect').validOptions; * @property {boolean} [promoteValues] (**default**: true) Promotes BSON values to native types where possible, set to false to only receive wrapper types * @property {boolean} [promoteBuffers] (**default**: false) Promotes Binary BSON values to native Node Buffers * @property {boolean} [promoteLongs] (**default**: true) Promotes long values to number if they fit inside the 53 bits resolution + * * @param {boolean} [bsonRegExp] (**default**: false) By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned. * @property {boolean} [domainsEnabled] (**default**: false) Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit * @property {object} [validateOptions] (**default**: false) Validate MongoClient passed in options for correctness * @property {string} [appname] (**default**: undefined) The name of the application that created this MongoClient instance. MongoDB 3.4 and newer will print this value in the server log upon establishing each connection. It is also recorded in the slow query log and profile collections diff --git a/lib/operations/command.js b/lib/operations/command.js index fd18a543c5..46ac336ef2 100644 --- a/lib/operations/command.js +++ b/lib/operations/command.js @@ -21,6 +21,7 @@ const debugFields = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'bufferMaxEntries', 'numberOfRetries', 'retryMiliSeconds', diff --git a/lib/operations/connect.js b/lib/operations/connect.js index 4533d2847b..960497f781 100644 --- a/lib/operations/connect.js +++ b/lib/operations/connect.js @@ -122,6 +122,7 @@ const validOptionNames = [ 'promoteValues', 'promoteBuffers', 'promoteLongs', + 'bsonRegExp', 'domainsEnabled', 'checkServerIdentity', 'validateOptions', diff --git a/lib/operations/db_ops.js b/lib/operations/db_ops.js index 8f9b89046b..a2e602e9f6 100644 --- a/lib/operations/db_ops.js +++ b/lib/operations/db_ops.js @@ -23,6 +23,7 @@ const debugFields = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'bufferMaxEntries', 'numberOfRetries', 'retryMiliSeconds', diff --git a/lib/topologies/mongos.js b/lib/topologies/mongos.js index bf30d20ebe..784d3b4ef8 100644 --- a/lib/topologies/mongos.js +++ b/lib/topologies/mongos.js @@ -54,6 +54,7 @@ var legalOptionNames = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'promiseLibrary', 'monitorCommands' ]; diff --git a/lib/topologies/replset.js b/lib/topologies/replset.js index 80701f5d3e..90ca54362a 100644 --- a/lib/topologies/replset.js +++ b/lib/topologies/replset.js @@ -60,6 +60,7 @@ var legalOptionNames = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'maxStalenessSeconds', 'promiseLibrary', 'minSize', diff --git a/lib/topologies/server.js b/lib/topologies/server.js index 0abaad3dba..77507208d8 100644 --- a/lib/topologies/server.js +++ b/lib/topologies/server.js @@ -56,6 +56,7 @@ var legalOptionNames = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'compression', 'promiseLibrary', 'monitorCommands' diff --git a/test/functional/unified-spec-runner/operations.ts b/test/functional/unified-spec-runner/operations.ts index 4c83f44aa3..37982cd5de 100644 --- a/test/functional/unified-spec-runner/operations.ts +++ b/test/functional/unified-spec-runner/operations.ts @@ -54,6 +54,8 @@ export interface BSONSerializeOptions extends Omit { promoteBuffers?: boolean; /** Promotes long values to number if they fit inside the 53 bits resolution */ promoteLongs?: boolean; + /** Promotes RegExp to BSONRegExp object if enabled */ + bsonRegExp?: boolean; /** Serialize functions on any object */ serializeFunctions?: boolean; /** Specify if the BSON serializer should ignore undefined fields */ diff --git a/test/unit/bson_regex.test.js b/test/unit/bson_regex.test.js new file mode 100644 index 0000000000..e0aecae5f6 --- /dev/null +++ b/test/unit/bson_regex.test.js @@ -0,0 +1,74 @@ +'use strict'; + +const expect = require('chai').expect; +const BSON = require('bson'); + +describe('BSONRegExp', () => { + describe('bsonRegExp option', () => { + it('should respond with BSONRegExp class with option passed to db', async function() { + let client; + try { + // create and connect to client + client = this.configuration.newClient(); + await client.connect(); + + const db = client.db('a', { bsonRegExp: true }); + const collection = db.collection('b'); + + await collection.insertOne({ regex: new BSON.BSONRegExp('abc', 'imx') }); + const res = await collection.findOne({ regex: new BSON.BSONRegExp('abc', 'imx') }); + + expect(res) + .has.property('regex') + .that.is.instanceOf(BSON.BSONRegExp); + } finally { + await client.close(); + } + }); + + it('should respond with BSONRegExp class with option passed to collection', async function() { + let client; + try { + // create and connect to client + client = this.configuration.newClient(); // bsonRegex + await client.connect(); + + const db = client.db('a'); + const collection = db.collection('b', { bsonRegExp: true }); + + await collection.insertOne({ regex: new BSON.BSONRegExp('abc', 'imx') }); + const res = await collection.findOne({ regex: new BSON.BSONRegExp('abc', 'imx') }); + + expect(res) + .has.property('regex') + .that.is.instanceOf(BSON.BSONRegExp); + } finally { + await client.close(); + } + }); + + it('should respond with BSONRegExp class with option passed to operation', async function() { + let client; + try { + // create and connect to client + client = this.configuration.newClient(); // bsonRegex + await client.connect(); + + const db = client.db('a'); + const collection = db.collection('b'); + + await collection.insertOne({ regex: new BSON.BSONRegExp('abc', 'imx') }); + const res = await collection.findOne( + { regex: new BSON.BSONRegExp('abc', 'imx') }, + { bsonRegExp: true } + ); + + expect(res) + .has.property('regex') + .that.is.instanceOf(BSON.BSONRegExp); + } finally { + await client.close(); + } + }); + }); +});