Skip to content

Commit

Permalink
WIP: upgrade to MongoDB driver 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Jan 20, 2021
1 parent bb39a54 commit 442d754
Show file tree
Hide file tree
Showing 13 changed files with 46 additions and 249 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters

```js
await mongoose.connect('mongodb://localhost/my_database', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
});
Expand Down
24 changes: 17 additions & 7 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ declare module 'mongoose' {
* if true, returns the raw result from the MongoDB driver
*/
rawResult?: boolean;
readPreference?: mongodb.ReadPreferenceMode;
readPreference?: string | mongodb.ReadPreferenceModeId;
/**
* An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
*/
Expand Down Expand Up @@ -1207,7 +1207,7 @@ declare module 'mongoose' {
*/
capped?: boolean | number | { size?: number; max?: number; autoIndexId?: boolean; };
/** Sets a default collation for every query and aggregation. */
collation?: mongodb.CollationDocument;
collation?: mongodb.CollationOptions;
/**
* Mongoose by default produces a collection name by passing the model name to the utils.toCollectionName
* method. This method pluralizes the name. Set this option if you need a different name for your collection.
Expand Down Expand Up @@ -1809,7 +1809,7 @@ declare module 'mongoose' {
circle(path: string, area: any): this;

/** Adds a collation to this op (MongoDB 3.4 and up) */
collation(value: mongodb.CollationDocument): this;
collation(value: mongodb.CollationOptions): this;

/** Specifies the `comment` option. */
comment(val: string): this;
Expand Down Expand Up @@ -2033,7 +2033,7 @@ declare module 'mongoose' {
projection(fields?: any | null): any;

/** Determines the MongoDB nodes from which to read. */
read(pref: string | mongodb.ReadPreferenceMode, tags?: any[]): this;
read(pref: string | mongodb.ReadPreferenceModeId, tags?: any[]): this;

/** Sets the readConcern option for the query. */
readConcern(level: string): this;
Expand Down Expand Up @@ -2159,6 +2159,16 @@ declare module 'mongoose' {
wtimeout(ms: number): this;
}

type DotAndArrayNotation<AssignableType> = {
readonly [key: string]: AssignableType;
};

type ReadonlyPartial<TSchema> = {
readonly [key in keyof TSchema]?: TSchema[key];
};

type MatchKeysAndValues<TSchema> = ReadonlyPartial<TSchema> & DotAndArrayNotation<any>;

type _FilterQuery<T> = {
[P in keyof T]?: P extends '_id'
? [Extract<T[P], mongodb.ObjectId>] extends [never]
Expand All @@ -2172,7 +2182,7 @@ declare module 'mongoose' {

export type FilterQuery<T> = _FilterQuery<DocumentDefinition<T>>;

export type UpdateQuery<T> = mongodb.UpdateQuery<DocumentDefinition<T>> & mongodb.MatchKeysAndValues<DocumentDefinition<T>>;
export type UpdateQuery<T> = mongodb.UpdateQuery<DocumentDefinition<T>> & MatchKeysAndValues<DocumentDefinition<T>>;

type _AllowStringsForIds<T> = {
[K in keyof T]: [Extract<T[K], mongodb.ObjectId>] extends [never] ? T[K] : T[K] | string;
Expand Down Expand Up @@ -2274,7 +2284,7 @@ declare module 'mongoose' {
catch: Promise<R>['catch'];

/** Adds a collation. */
collation(options: mongodb.CollationDocument): this;
collation(options: mongodb.CollationOptions): this;

/** Appends a new $count operator to this aggregate pipeline. */
count(countName: string): this;
Expand Down Expand Up @@ -2327,7 +2337,7 @@ declare module 'mongoose' {
pipeline(): any[];

/** Sets the readPreference option for the aggregation query. */
read(pref: string | mongodb.ReadPreferenceMode, tags?: any[]): this;
read(pref: string | mongodb.ReadPreferenceModeId, tags?: any[]): this;

/** Sets the readConcern level for the aggregation query. */
readConcern(level: string): this;
Expand Down
27 changes: 9 additions & 18 deletions lib/aggregate.js
Original file line number Diff line number Diff line change
Expand Up @@ -975,25 +975,16 @@ Aggregate.prototype.exec = function(callback) {
}

const options = utils.clone(this.options || {});
collection.aggregate(this._pipeline, options, (error, cursor) => {
if (error) {
const _opts = { error: error };
return model.hooks.execPost('aggregate', this, [null], _opts, error => {
if (error) {
return cb(error);
}
return cb(null);
});
}
cursor.toArray((error, result) => {
const _opts = { error: error };
model.hooks.execPost('aggregate', this, [result], _opts, (error, result) => {
if (error) {
return cb(error);
}

cb(null, result);
});
const cursor = collection.aggregate(this._pipeline, options);
cursor.toArray((error, result) => {
const _opts = { error: error };
model.hooks.execPost('aggregate', this, [result], _opts, (error, result) => {
if (error) {
return cb(error);
}

cb(null, result);
});
});
});
Expand Down
93 changes: 1 addition & 92 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ const mongodb = require('mongodb');
const pkg = require('../package.json');
const utils = require('./utils');

const parseConnectionString = require('mongodb/lib/core').parseConnectionString;

const arrayAtomicsSymbol = require('./helpers/symbols').arrayAtomicsSymbol;
const sessionNewDocuments = require('./helpers/symbols').sessionNewDocuments;

Expand Down Expand Up @@ -776,50 +774,13 @@ Connection.prototype.openUri = function(uri, options, callback) {
}
delete options.dbName;

if (!('promiseLibrary' in options)) {
options.promiseLibrary = PromiseProvider.get();
}
if (!('useNewUrlParser' in options)) {
if ('useNewUrlParser' in this.base.options) {
options.useNewUrlParser = this.base.options.useNewUrlParser;
} else {
options.useNewUrlParser = false;
}
}
if (!utils.hasUserDefinedProperty(options, 'useUnifiedTopology')) {
if (utils.hasUserDefinedProperty(this.base.options, 'useUnifiedTopology')) {
options.useUnifiedTopology = this.base.options.useUnifiedTopology;
} else {
options.useUnifiedTopology = false;
}
}
if (!utils.hasUserDefinedProperty(options, 'driverInfo')) {
options.driverInfo = {
name: 'Mongoose',
version: pkg.version
};
}

const parsePromise = new Promise((resolve, reject) => {
parseConnectionString(uri, options, (err, parsed) => {
if (err) {
return reject(err);
}
if (dbName) {
this.name = dbName;
} else if (parsed.defaultDatabase) {
this.name = parsed.defaultDatabase;
} else {
this.name = get(parsed, 'auth.db', null);
}
this.host = get(parsed, 'hosts.0.host', 'localhost');
this.port = get(parsed, 'hosts.0.port', 27017);
this.user = this.user || get(parsed, 'auth.username');
this.pass = this.pass || get(parsed, 'auth.password');
resolve();
});
});

const promise = new Promise((resolve, reject) => {
const client = new mongodb.MongoClient(uri, options);
_this.client = client;
Expand All @@ -836,7 +797,7 @@ Connection.prototype.openUri = function(uri, options, callback) {
});

const serverSelectionError = new ServerSelectionError();
this.$initialConnection = Promise.all([promise, parsePromise]).
this.$initialConnection = promise.
then(() => this).
catch(err => {
if (err != null && err.name === 'MongoServerSelectionError') {
Expand Down Expand Up @@ -911,61 +872,9 @@ function _setClient(conn, client, options, dbName) {
_handleReconnect();
}
});

db.on('close', function() {
const type = get(db, 's.topology.s.description.type', '');
if (type !== 'ReplicaSetWithPrimary') {
// Implicitly emits 'disconnected'
conn.readyState = STATES.disconnected;
}
});
}
}

// Backwards compat for mongoose 4.x
db.on('reconnect', function() {
_handleReconnect();
});
db.s.topology.on('reconnectFailed', function() {
conn.emit('reconnectFailed');
});

if (!options.useUnifiedTopology) {
db.s.topology.on('left', function(data) {
conn.emit('left', data);
});
}
db.s.topology.on('joined', function(data) {
conn.emit('joined', data);
});
db.s.topology.on('fullsetup', function(data) {
conn.emit('fullsetup', data);
});
if (get(db, 's.topology.s.coreTopology.s.pool') != null) {
db.s.topology.s.coreTopology.s.pool.on('attemptReconnect', function() {
conn.emit('attemptReconnect');
});
}
if (!options.useUnifiedTopology || !type.startsWith('ReplicaSet')) {
db.on('close', function() {
// Implicitly emits 'disconnected'
conn.readyState = STATES.disconnected;
});
}

if (!options.useUnifiedTopology) {
client.on('left', function() {
if (conn.readyState === STATES.connected &&
get(db, 's.topology.s.coreTopology.s.replicaSetState.topologyType') === 'ReplicaSetNoPrimary') {
conn.readyState = STATES.disconnected;
}
});
}

db.on('timeout', function() {
conn.emit('timeout');
});

delete conn.then;
delete conn.catch;
conn.readyState = STATES.connected;
Expand Down
2 changes: 1 addition & 1 deletion lib/drivers/node-mongodb-native/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ function iter(i) {
};
}

for (const key of Object.keys(Collection.prototype)) {
for (const key of Object.getOwnPropertyNames(Collection.prototype)) {
// Janky hack to work around gh-3005 until we can get rid of the mongoose
// collection abstraction
const descriptor = Object.getOwnPropertyDescriptor(Collection.prototype, key);
Expand Down
49 changes: 0 additions & 49 deletions lib/drivers/node-mongodb-native/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ NativeConnection.prototype.useDb = function(name, options) {
newConn.client = _this.client;
newConn.db = _this.client.db(name);
newConn.onOpen();
// setup the events appropriately
listen(newConn);
}

newConn.name = name;
Expand All @@ -111,53 +109,6 @@ NativeConnection.prototype.useDb = function(name, options) {
return newConn;
};

/*!
* Register listeners for important events and bubble appropriately.
*/

function listen(conn) {
if (conn.db._listening) {
return;
}
conn.db._listening = true;

conn.db.on('close', function(force) {
if (conn._closeCalled) return;

// the driver never emits an `open` event. auto_reconnect still
// emits a `close` event but since we never get another
// `open` we can't emit close
if (conn.db.serverConfig.autoReconnect) {
conn.readyState = STATES.disconnected;
conn.emit('close');
return;
}
conn.onClose(force);
});
conn.db.on('error', function(err) {
conn.emit('error', err);
});
conn.db.on('reconnect', function() {
conn.readyState = STATES.connected;
conn.emit('reconnect');
conn.emit('reconnected');
conn.onOpen();
});
conn.db.on('timeout', function(err) {
conn.emit('timeout', err);
});
conn.db.on('open', function(err, db) {
if (STATES.disconnected === conn.readyState && db && db.databaseName) {
conn.readyState = STATES.connected;
conn.emit('reconnect');
conn.emit('reconnected');
}
});
conn.db.on('parseError', function(err) {
conn.emit('parseError', err);
});
}

/**
* Closes the connection
*
Expand Down
24 changes: 10 additions & 14 deletions lib/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -2041,20 +2041,16 @@ Query.prototype._find = wrapThunk(function(callback) {
options.projection = this._fieldsForExec();
const filter = this._conditions;

this._collection.collection.find(filter, options, (err, cursor) => {
if (err) {
return cb(err);
}
if (options.explain) {
return cursor.explain(cb);
}
try {
return cursor.toArray(cb);
} catch (err) {
cb(err);
}
});
return null;
const cursor = this._collection.collection.find(filter, options);

if (options.explain) {
return cursor.explain(cb);
}
try {
return cursor.toArray(cb);
} catch (err) {
return cb(err);
}
});

/**
Expand Down
4 changes: 1 addition & 3 deletions lib/validoptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ const VALID_OPTIONS = Object.freeze([
'toObject',
'typePojoToMixed',
'useCreateIndex',
'useNewUrlParser',
'usePushEach',
'useUnifiedTopology'
'usePushEach'
]);

module.exports = VALID_OPTIONS;
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@
],
"license": "MIT",
"dependencies": {
"@types/mongodb": "^3.5.27",
"bson": "^1.1.4",
"bson": "^4.2.2",
"kareem": "2.3.2",
"mongodb": "3.6.3",
"mongodb": "4.0.0-beta.0",
"mongoose-legacy-pluralize": "1.0.2",
"mpath": "0.8.3",
"mquery": "3.2.3",
Expand Down
3 changes: 0 additions & 3 deletions test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ if (process.env.PRINT_COLLECTIONS) {

// For 3.1.3 deprecations
mongoose.set('useCreateIndex', true);
mongoose.set('useNewUrlParser', true);
// 3.3.x deprecations
mongoose.set('useUnifiedTopology', true);

/**
* Override all Collection related queries to keep count
Expand Down
Loading

0 comments on commit 442d754

Please sign in to comment.