Skip to content

Commit 71d85b1

Browse files
authored
Merge pull request #5106 from Automattic/5105
Make sharding into a plugin instead of core
2 parents 4b84e5b + 9a19a82 commit 71d85b1

15 files changed

+164
-152
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ docs/
22
bin/
33
test/triage/
44
test/model.discriminator.test.js
5+
tools/
56
test/es6/

lib/document.js

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,6 @@ Document.prototype.init = function(doc, opts, fn) {
328328
}
329329

330330
init(this, doc, this._doc);
331-
this.$__storeShard();
332331

333332
this.emit('init', this);
334333
this.constructor.emit('init', this);
@@ -416,44 +415,6 @@ function init(self, obj, doc, prefix) {
416415
}
417416
}
418417

419-
/**
420-
* Stores the current values of the shard keys.
421-
*
422-
* ####Note:
423-
*
424-
* _Shard key values do not / are not allowed to change._
425-
*
426-
* @api private
427-
* @method $__storeShard
428-
* @memberOf Document
429-
*/
430-
431-
Document.prototype.$__storeShard = function() {
432-
// backwards compat
433-
var key = this.schema.options.shardKey || this.schema.options.shardkey;
434-
if (!(key && utils.getFunctionName(key.constructor) === 'Object')) {
435-
return;
436-
}
437-
438-
var orig = this.$__.shardval = {},
439-
paths = Object.keys(key),
440-
len = paths.length,
441-
val;
442-
443-
for (var i = 0; i < len; ++i) {
444-
val = this.getValue(paths[i]);
445-
if (isMongooseObject(val)) {
446-
orig[paths[i]] = val.toObject({depopulate: true, _isNested: true});
447-
} else if (val !== null && val !== undefined && val.valueOf &&
448-
// Explicitly don't take value of dates
449-
(!val.constructor || utils.getFunctionName(val.constructor) !== 'Date')) {
450-
orig[paths[i]] = val.valueOf();
451-
} else {
452-
orig[paths[i]] = val;
453-
}
454-
}
455-
};
456-
457418
/*!
458419
* Set up middleware support
459420
*/

lib/index.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var validateBeforeSave = require('./plugins/validateBeforeSave');
2222

2323
var Aggregate = require('./aggregate');
2424
var PromiseProvider = require('./promise_provider');
25+
var shardingPlugin = require('./plugins/sharding');
2526

2627
/**
2728
* Mongoose constructor.
@@ -34,7 +35,6 @@ var PromiseProvider = require('./promise_provider');
3435

3536
function Mongoose() {
3637
this.connections = [];
37-
this.plugins = [];
3838
this.models = {};
3939
this.modelSchemas = {};
4040
// default global options
@@ -45,6 +45,21 @@ function Mongoose() {
4545
conn.models = this.models;
4646
}
4747

48+
/*!
49+
* ignore
50+
*/
51+
52+
Object.defineProperty(Mongoose.prototype, 'plugins', {
53+
configurable: false,
54+
enumerable: true,
55+
writable: false,
56+
value: [
57+
[saveSubdocs, { deduplicate: true }],
58+
[validateBeforeSave, { deduplicate: true }],
59+
[shardingPlugin, { deduplicate: true }]
60+
]
61+
});
62+
4863
/**
4964
* Expose connection states for user-land
5065
*
@@ -366,13 +381,6 @@ Mongoose.prototype.model = function(name, schema, collection, skipInit) {
366381
}
367382

368383
if (schema) {
369-
// Reverse order because these both unshift()
370-
if (!schema._plugins.saveSubdocs) {
371-
schema.plugin(saveSubdocs);
372-
}
373-
if (!schema._plugins.validateBeforeSave) {
374-
schema.plugin(validateBeforeSave);
375-
}
376384
this._applyPlugins(schema);
377385
}
378386

lib/model.js

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ Model.prototype.$__save = function(options, callback) {
218218
}
219219

220220
_this.$__reset();
221-
_this.$__storeShard();
222221

223222
var numAffected = 0;
224223
if (result) {
@@ -669,7 +668,7 @@ Model.prototype.increment = function increment() {
669668
};
670669

671670
/**
672-
* Returns a query object which applies shardkeys if they exist.
671+
* Returns a query object
673672
*
674673
* @api private
675674
* @method $__where
@@ -679,22 +678,10 @@ Model.prototype.increment = function increment() {
679678
Model.prototype.$__where = function _where(where) {
680679
where || (where = {});
681680

682-
var paths,
683-
len;
684-
685681
if (!where._id) {
686682
where._id = this._doc._id;
687683
}
688684

689-
if (this.$__.shardval) {
690-
paths = Object.keys(this.$__.shardval);
691-
len = paths.length;
692-
693-
for (var i = 0; i < len; ++i) {
694-
where[paths[i]] = this.$__.shardval[paths[i]];
695-
}
696-
}
697-
698685
if (this._doc._id == null) {
699686
return new Error('No _id found on document!');
700687
}

lib/plugins/saveSubdocs.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ var each = require('async/each');
77
*/
88

99
module.exports = function(schema) {
10-
schema._plugins.saveSubdocs = true;
11-
1210
schema.callQueue.unshift(['pre', ['save', function(next) {
1311
if (this.ownerDocument) {
1412
next();

lib/plugins/sharding.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use strict';
2+
3+
var utils = require('../utils');
4+
5+
module.exports = function shardingPlugin(schema) {
6+
schema.post('init', function() {
7+
storeShard.call(this);
8+
return this;
9+
});
10+
schema.pre('save', function(next) {
11+
applyWhere.call(this);
12+
next();
13+
});
14+
schema.post('save', function() {
15+
storeShard.call(this);
16+
});
17+
};
18+
19+
function applyWhere() {
20+
var paths;
21+
var len;
22+
23+
if (this.$__.shardval) {
24+
paths = Object.keys(this.$__.shardval);
25+
len = paths.length;
26+
27+
this.$where = this.$where || {};
28+
for (var i = 0; i < len; ++i) {
29+
this.$where[paths[i]] = this.$__.shardval[paths[i]];
30+
}
31+
}
32+
}
33+
34+
/*!
35+
* Stores the current values of the shard keys.
36+
*
37+
* ####Note:
38+
*
39+
* _Shard key values do not / are not allowed to change._
40+
*
41+
* @api private
42+
* @method $__storeShard
43+
* @memberOf Document
44+
*/
45+
module.exports.storeShard = storeShard;
46+
47+
function storeShard() {
48+
// backwards compat
49+
var key = this.schema.options.shardKey || this.schema.options.shardkey;
50+
if (!(key && utils.getFunctionName(key.constructor) === 'Object')) {
51+
return;
52+
}
53+
54+
var orig = this.$__.shardval = {},
55+
paths = Object.keys(key),
56+
len = paths.length,
57+
val;
58+
59+
for (var i = 0; i < len; ++i) {
60+
val = this.getValue(paths[i]);
61+
if (utils.isMongooseObject(val)) {
62+
orig[paths[i]] = val.toObject({depopulate: true, _isNested: true});
63+
} else if (val !== null && val !== undefined && val.valueOf &&
64+
// Explicitly don't take value of dates
65+
(!val.constructor || utils.getFunctionName(val.constructor) !== 'Date')) {
66+
orig[paths[i]] = val.valueOf();
67+
} else {
68+
orig[paths[i]] = val;
69+
}
70+
}
71+
}

lib/plugins/validateBeforeSave.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
*/
66

77
module.exports = function(schema) {
8-
schema._plugins.validateBeforeSave = true;
9-
108
schema.callQueue.unshift(['pre', ['save', function(next, options) {
119
var _this = this;
1210
// Nested docs have their own presave

lib/schema.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function Schema(obj, options) {
8686
this.tree = {};
8787
this.query = {};
8888
this.childSchemas = [];
89-
this._plugins = {};
89+
this.plugins = [];
9090

9191
this.s = {
9292
hooks: new Kareem(),
@@ -273,7 +273,7 @@ Schema.prototype.clone = function() {
273273
s.callQueue = this.callQueue.map(function(f) { return f; });
274274
s.methods = utils.clone(this.methods);
275275
s.statics = utils.clone(this.statics);
276-
s._plugins = utils.clone(this._plugins);
276+
s.plugins = Array.prototype.slice.call(this.plugins);
277277
s.s.hooks = this.s.hooks.clone();
278278
return s;
279279
};
@@ -1113,6 +1113,17 @@ Schema.prototype.plugin = function(fn, opts) {
11131113
throw new Error('First param to `schema.plugin()` must be a function, ' +
11141114
'got "' + (typeof fn) + '"');
11151115
}
1116+
1117+
if (opts &&
1118+
opts.deduplicate) {
1119+
for (var i = 0; i < this.plugins.length; ++i) {
1120+
if (this.plugins[i].fn === fn) {
1121+
return this;
1122+
}
1123+
}
1124+
}
1125+
this.plugins.push({ fn: fn, opts: opts });
1126+
11161127
fn(this, opts);
11171128
return this;
11181129
};

lib/services/model/discriminator.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ module.exports = function discriminator(model, name, schema) {
8484
schema.options.id = id;
8585
schema.s.hooks = model.schema.s.hooks.merge(schema.s.hooks);
8686

87+
schema.plugins = Array.prototype.slice(baseSchema.plugins);
8788
schema.callQueue = baseSchema.callQueue.
8889
concat(schema.callQueue.slice(schema._defaultMiddleware.length));
8990
schema._requiredpaths = undefined; // reset just in case Schema#requiredPaths() was called on either schema

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"marked": "0.3.6",
4949
"mocha": "3.2.0",
5050
"mongoose-long": "0.1.1",
51+
"mongodb-topology-manager": "1.0.11",
5152
"node-static": "0.7.7",
5253
"power-assert": "1.4.1",
5354
"q": "1.4.1",

test/connection.test.js

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,6 @@ describe('connections:', function() {
141141

142142
var mongod = 'mongodb://localhost:27017';
143143

144-
var repl1 = process.env.MONGOOSE_SET_TEST_URI;
145-
var repl2 = repl1.replace('mongodb://', '').split(',');
146-
repl2.push(repl2.shift());
147-
repl2 = 'mongodb://' + repl2.join(',');
148-
149144
describe('with different host/port', function() {
150145
it('non-replica set', function(done) {
151146
var db = mongoose.createConnection();
@@ -195,59 +190,6 @@ describe('connections:', function() {
195190
});
196191
});
197192
});
198-
199-
it('replica set', function(done) {
200-
var db = mongoose.createConnection();
201-
202-
db.openSet(repl1, function(err) {
203-
if (err) {
204-
return done(err);
205-
}
206-
207-
var hosts = db.hosts.slice();
208-
var db1 = db.db;
209-
210-
db.close(function(err) {
211-
if (err) {
212-
return done(err);
213-
}
214-
215-
db.openSet(repl2, function(err) {
216-
if (err) {
217-
return done(err);
218-
}
219-
220-
db.hosts.forEach(function(host, i) {
221-
assert.notEqual(host.port, hosts[i].port);
222-
});
223-
assert.ok(db1 !== db.db);
224-
225-
hosts = db.hosts.slice();
226-
var db2 = db.db;
227-
228-
db.close(function(err) {
229-
if (err) {
230-
return done(err);
231-
}
232-
233-
db.openSet(repl1, function(err) {
234-
if (err) {
235-
return done(err);
236-
}
237-
238-
db.hosts.forEach(function(host, i) {
239-
assert.notEqual(host.port, hosts[i].port);
240-
});
241-
assert.ok(db2 !== db.db);
242-
243-
db.close();
244-
done();
245-
});
246-
});
247-
});
248-
});
249-
});
250-
});
251193
});
252194
});
253195

test/document.unit.test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
* Module dependencies.
33
*/
44

5-
var start = require('./common');
65
var assert = require('power-assert');
6+
var start = require('./common');
7+
var storeShard = require('../lib/plugins/sharding').storeShard;
8+
79
var mongoose = start.mongoose;
810

911
describe('sharding', function() {
@@ -22,7 +24,7 @@ describe('sharding', function() {
2224
var currentTime = new Date();
2325
d._doc = {date: currentTime};
2426

25-
d.$__storeShard();
27+
storeShard.call(d);
2628
assert.equal(d.$__.shardval.date, currentTime);
2729
done();
2830
});

0 commit comments

Comments
 (0)