From e4a9a572427666fd1a89576dadf50b9c452e1659 Mon Sep 17 00:00:00 2001 From: Andy Mina Date: Mon, 28 Jun 2021 09:24:39 -0400 Subject: [PATCH] fix(NODE-3150): added bsonRegExp option for v3.6 (#2843) --- 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 | 43 +++++++++++++++++++ 23 files changed, 112 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 c9d34960c8..5870470c74 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 491df52ceb..369a66089e 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 7adb0dfb95..2cf0591d2c 100644 --- a/lib/core/sdam/server.js +++ b/lib/core/sdam/server.js @@ -50,6 +50,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 43bf758205..ebc7087001 100644 --- a/lib/core/topologies/server.js +++ b/lib/core/topologies/server.js @@ -47,6 +47,7 @@ var debugFields = [ 'promoteLongs', 'promoteValues', 'promoteBuffers', + 'bsonRegExp', 'servername' ]; @@ -89,6 +90,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 e65d3bbb49..769275f408 100644 --- a/lib/operations/command.js +++ b/lib/operations/command.js @@ -22,6 +22,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 fb9c492da8..785af776a0 100644 --- a/lib/operations/db_ops.js +++ b/lib/operations/db_ops.js @@ -24,6 +24,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..8a45bc1437 --- /dev/null +++ b/test/unit/bson_regex.test.js @@ -0,0 +1,43 @@ +'use strict'; + +const expect = require('chai').expect; +const BSONRegExp = require('bson').BSONRegExp; + +describe('BSONRegExp', () => { + describe('bsonRegExp option', () => { + // define option for tests to use + const option = { bsonRegExp: true }; + for (const passOptionTo of ['client', 'db', 'collection', 'operation']) { + it(`should respond with BSONRegExp class with option passed to ${passOptionTo}`, function(done) { + const client = this.configuration.newClient(passOptionTo === 'client' ? option : undefined); + let collection; + + client + .connect() + .then(() => { + const db = client.db('bson_regex_db', passOptionTo === 'db' ? option : undefined); + collection = db.collection( + 'bson_regex_coll', + passOptionTo === 'collection' ? option : undefined + ); + }) + .then(() => collection.insertOne({ regex: new BSONRegExp('abc', 'imx') })) + .then(() => + collection.findOne( + { regex: new BSONRegExp('abc', 'imx') }, + passOptionTo === 'operation' ? option : undefined + ) + ) + .then(res => + expect(res) + .has.property('regex') + .that.is.instanceOf(BSONRegExp) + ) + .then( + () => client.close(done), + err => client.close(() => done(err)) + ); + }); + } + }); +});