Skip to content
Browse files

Performance improvements in wrapping objects

  • Loading branch information...
1 parent b4ec2ce commit a8971584239461271db4c5fb649dbdb5f1476f84 @JoshuaGross committed Nov 4, 2012
Showing with 56 additions and 27 deletions.
  1. +36 −16 lib/mongoose-subpopulate.js
  2. +1 −1 package.json
  3. +19 −10 test/mongoose.js
View
52 lib/mongoose-subpopulate.js
@@ -26,11 +26,15 @@ var wrapSchema = exports.wrapSchema = function wrapSchema (schema) {
}
return function (err, result) {
if (callback.length === 2) {
- return callback(err, wrapModelObject(result));
+ wrapModelObject(result, function (wrapped) {
+ return callback(err, wrapped);
+ });
} else if (err) {
throw new Error('Database error: '+errMsg+' / '+err);
} else {
- return callback(wrapModelObject(result));
+ wrapModelObject(result, function (wrapped) {
+ return callback(wrapped);
+ });
}
};
};
@@ -286,19 +290,35 @@ function getCallerDetails () {
// 1) Directly access the _id attribute as a string
// 2) Get and set attributes of the object; all changes are synced immediately with the mongoose link
// 3) Get a bare dictionary of the model and any populated descendants
-function wrapModelObject (object) {
+function wrapModelObject (object, callback) {
if (object === null || object === undefined) {
- return object;
+ return (callback ? callback(object) : object);
}
// Is this an array?
if (!object._schema /* 2.7 */ && !object.schema /* 3.x */) {
- for (var i in object) {
- if (object[i] && (object[i]._schema || object[i].schema)) {
- object[i] = wrapModelObject(object[i]);
+ if (callback) {
+ return async.map(object, function (obj, iterate) {
+ if (obj && (obj._schema || obj.schema)) {
+ process.nextTick(function () {
+ wrapModelObject(obj, function (wrappedObject) {
+ iterate(null, wrappedObject);
+ });
+ });
+ } else {
+ iterate(null, obj);
+ }
+ }, function (err, wrappedObject) {
+ return callback(wrappedObject);
+ });
+ } else {
+ for (var i in object) {
+ if (object[i] && (object[i]._schema || object[i].schema)) {
+ object[i] = wrapModelObject(object[i]);
+ }
}
+ return object;
}
- return object;
}
var wrappedObject = new (function wrapped () {})();
@@ -307,16 +327,16 @@ function wrapModelObject (object) {
for (var i in object) {
if (typeof object[i] === 'function') {
- if ((!i.match(/^to/) || i.match(/^toObject/)) && 'inspect' != i) {
+ if ((i.substr(0,2) !== 'to' || i === 'toObject') && 'inspect' !== i) {
(function (attr) {
- wrappedObject[attr] = function () {
+ wrappedObject.__proto__[attr] = function () {
return object[attr].apply(object, arguments);
}
})(i);
}
} else {
(function (attr) {
- wrappedObject.__defineGetter__(attr, function () {
+ wrappedObject.__proto__.__defineGetter__(attr, function () {
return object[attr];
});
})(i);
@@ -327,7 +347,7 @@ function wrapModelObject (object) {
var schema = (object._schema || object.schema).paths;
for (var i in schema) {
(function (attr) {
- wrappedObject.__defineGetter__(attr, function () {
+ wrappedObject.__proto__.__defineGetter__(attr, function () {
// Sometimes the object will have an undefined value, but something is hanging out in object._docs
('undefined' === typeof object[attr] && 'undefined' !== typeof object._doc && 'undefined' !== typeof object._doc[attr]) && (object[attr] = object._doc[attr]);
@@ -357,7 +377,7 @@ function wrapModelObject (object) {
return object[attr];
}
});
- wrappedObject.__defineSetter__(attr, function (value) {
+ wrappedObject.__proto__.__defineSetter__(attr, function (value) {
// Cache object references; Mongoose casts them to IDs and they're sort of lost.
if (value && value.mongooseLink) {
wrappedObject.populatedObjects[value._id] = value;
@@ -376,11 +396,11 @@ function wrapModelObject (object) {
// Allow all methods (from plugins, etc) to be accessed
for (var i in wrappedObject.schema.methods) {
(function (methodName) {
- wrappedObject[methodName] = wrappedObject.schema.methods[methodName];
+ wrappedObject.__proto__[methodName] = wrappedObject.schema.methods[methodName];
})(i);
}
- wrappedObject.getBare = function (callback) {
+ wrappedObject.__proto__.getBare = function (callback) {
var keys = Object.keys(wrappedObject.schema.paths);
var bareDictionary = {};
@@ -399,7 +419,7 @@ function wrapModelObject (object) {
});
};
- return wrappedObject;
+ return (callback ? callback(wrappedObject) : wrappedObject);
}
exports.extendMongoose = function (mongooseIn, defineModels) {
mongoose = mongooseIn;
View
2 package.json
@@ -1,6 +1,6 @@
{
"name": "mongoose-subpopulate",
- "version": "0.1.10",
+ "version": "0.1.11",
"main": "./lib/mongoose-subpopulate.js",
"scripts": {},
"repository": {
View
29 test/mongoose.js
@@ -146,12 +146,12 @@ describe('mongoose wrapping of find, exec, etc', function () {
}
});
// TODO: rigorously test this
- /*it('should handle errors from object creation', function (done) {
- var m = common.db();
+ //it('should handle errors from object creation', function (done) {
+ //var m = common.db();
// leave necessary fields empty
- var u = new m.User();
- u.save(done);
- });*/
+ //var u = new m.User();
+ //u.save(done);
+ //});
it('should wrap errors from findOne', function (done) {
var m = common.db();
m.User.findOne({ _id: findOneID }, function (user) {
@@ -370,9 +370,9 @@ describe('mongoose additions bugs', function () {
});
});
});
-/*describe('mongoose large record handling', function () {
+describe('mongoose large record handling', function () {
it('should be able to create large amounts of records', function (done) {
- this.timeout(10000);
+ this.timeout(0);
var m = common.db();
var ids = [];
for (var i = 0; i < 1000; i++) {
@@ -391,11 +391,20 @@ describe('mongoose additions bugs', function () {
});
});
it('should be able to fetch large amounts of records', function (done) {
- this.timeout(10000);
+ this.timeout(0);
var m = common.db();
m.User.find().exec(function (users) {
expect(users.length).to.be.greaterThan(1000);
- done();
+ async.map(users, function (u, iterate) {
+ var newEmail = u.email+'.uk';
+ u.email = newEmail;
+ u.save(function (err, newU) {
+ expect(newU.email).to.be(newEmail);
+ iterate(null, null);
+ });
+ }, function () {
+ done();
+ });
});
});
-});*/
+});

0 comments on commit a897158

Please sign in to comment.
Something went wrong with that request. Please try again.