Skip to content

Commit

Permalink
feat(urlParser): use core URL parser
Browse files Browse the repository at this point in the history
Adds the ability to opt-in to using the new spec-compliant url
parser.

Fixes NODE-1304
  • Loading branch information
daprahamian committed Apr 27, 2018
1 parent 3c31e31 commit c1c5d8d
Showing 1 changed file with 63 additions and 6 deletions.
69 changes: 63 additions & 6 deletions lib/mongo_client.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'use strict';

const parse = require('./url_parser');
const parse = require('mongodb-core').parseConnectionString;
const Server = require('./topologies/server');
const Mongos = require('./topologies/mongos');
const ReplSet = require('./topologies/replset');
const EventEmitter = require('events').EventEmitter;
const inherits = require('util').inherits;
const deprecate = require('util').deprecate;
const ReadPreference = require('mongodb-core').ReadPreference;
const Logger = require('mongodb-core').Logger;
const MongoError = require('mongodb-core').MongoError;
Expand All @@ -17,6 +18,12 @@ const authenticate = require('./authenticate');
const ServerSessionPool = require('mongodb-core').Sessions.ServerSessionPool;
const executeOperation = require('./utils').executeOperation;

const legacyParse = deprecate(
require('./url_parser'),
'current URL string parser is deprecated, and will be removed in a future version. ' +
'To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.'
);

/**
* @fileOverview The **MongoClient** class is a class that allows for making Connections to MongoDB.
*
Expand Down Expand Up @@ -107,9 +114,54 @@ var validOptionNames = [
'auto_reconnect',
'minSize',
'monitorCommands',
'retryWrites'
'retryWrites',
'useNewUrlParser'
];

const validOptionsLowerCaseToCamelCase = validOptionNames.reduce((obj, name) => {
obj[name.toLowerCase()] = name;
return obj;
}, {});

function transformUrlOptions(_object) {
let object = Object.assign({ servers: _object.hosts }, _object.options);
for (let name in object) {
const camelCaseName = validOptionsLowerCaseToCamelCase[name];
if (camelCaseName) {
object[camelCaseName] = object[name];
}
}
if (_object.auth) {
const auth = _object.auth;
for (let i in auth) {
if (auth[i]) {
object[i] = auth[i];
}
}
if (auth.username) {
object.auth = auth;
object.user = auth.username;
}
if (auth.db) {
object.dbName = auth.db;
}
}
if (object.maxpoolsize) {
object.poolSize = object.maxpoolsize;
}
if (object.readconcernlevel) {
object.readConcern = { level: object.readconcernlevel };
}
if (object.wtimeoutms) {
object.wtimeout = object.wtimeoutms;
}
return object;
}

function legacyTransformUrlOptions(object) {
return mergeOptions(createUnifiedOptions({}, object), object, false);
}

var ignoreOptionNames = ['native_parser'];
var legacyOptionNames = ['server', 'replset', 'replSet', 'mongos', 'db'];

Expand Down Expand Up @@ -202,6 +254,7 @@ function validOptions(options) {
* @param {boolean} [options.auto_reconnect=true] Enable auto reconnecting for single server instances
* @param {boolean} [options.monitorCommands=false] Enable command monitoring for this client
* @param {number} [options.minSize] If present, the connection pool will be initialized with minSize connections, and will never dip below minSize connections
* @param {boolean} [options.useNewUrlParser=false] Determines whether or not to use the new url parser
* @param {MongoClient~connectCallback} [callback] The command result callback
* @return {MongoClient} a MongoClient instance
*/
Expand Down Expand Up @@ -921,14 +974,18 @@ var connect = function(self, url, options, callback) {
);
}

parse(url, options, function(err, object) {
const parseFn = options.useNewUrlParser ? parse : legacyParse;
const transform = options.useNewUrlParser ? transformUrlOptions : legacyTransformUrlOptions;

parseFn(url, options, function(err, _object) {
// Do not attempt to connect if parsing error
if (err) return callback(err);

// Flatten
const object = transform(_object);

// Parse the string
var _finalOptions = createUnifiedOptions({}, object);
_finalOptions = mergeOptions(_finalOptions, object, false);
_finalOptions = createUnifiedOptions(_finalOptions, options);
const _finalOptions = createUnifiedOptions(object, options);

// Check if we have connection and socket timeout set
if (_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS = 360000;
Expand Down

0 comments on commit c1c5d8d

Please sign in to comment.