Comparing version 1.0.13 to 1.0.14
1.0.14 / 2011-02-17 | ||
=================== | ||
* Fix for arrays within subdocuments [brian] | ||
1.0.13 / 2011-02-16 | ||
@@ -3,0 +8,0 @@ =================== |
@@ -256,3 +256,3 @@ | ||
exports.version = '1.0.13'; | ||
exports.version = '1.0.14'; | ||
@@ -259,0 +259,0 @@ /** |
@@ -95,49 +95,28 @@ | ||
var type = data.value | ||
, schema = data.schema; | ||
, schema = data.schema | ||
, atomics, val, obj; | ||
// a MongooseArray or MongooseNumber | ||
if (type._path && type.doAtomics) { | ||
['$push', '$pull'].forEach( function (opType) { | ||
var ops = type._atomics.filter( function (op) { | ||
return op[0] === opType; | ||
}) | ||
, opsAll = type._atomics.filter( function (op) { | ||
return op[0] === (opType + 'All'); | ||
}); | ||
if (ops.length > 1 || (ops.length === 1 && opsAll.length > 0)) { | ||
// If we have more than one $push (or $pull) | ||
// Or if we have at least one $push and at least one $pushAll | ||
// (or $pull and $pullAll) | ||
// Then collapse everything into one $pushAll (or $pullAll) | ||
type._atomics = type._atomics.filter( function (op) { | ||
return op[0] !== opType; | ||
}); | ||
if (opsAll.length > 0) { | ||
type._atomics = type._atomics.filter( function (op) { | ||
return op[0] !== (opType + 'All'); | ||
}); | ||
atomics = type._atomics; | ||
for (var op in atomics) { | ||
if (op === '$pushAll' || op === '$pullAll') { | ||
if (atomics[op].length === 1) { | ||
val = atomics[op][0]; | ||
delete atomics[op]; | ||
op = op.replace('All', ''); | ||
atomics[op] = val; | ||
} | ||
var whatToAll = []; | ||
opsAll.forEach( function (op) { | ||
whatToAll = whatToAll.concat(op[1]); | ||
}); | ||
whatToAll = whatToAll.concat( ops.map( function (op) { | ||
return op[1]; | ||
}) ); | ||
type._atomics.push([opType + 'All', whatToAll]); | ||
} | ||
}); | ||
type._atomics.forEach( function (op) { | ||
var obj = delta[op[0]] = delta[op[0]] || {}; | ||
if (op[0] === '$pull' || op[0] === '$push') { | ||
if (op[1].constructor !== Object) { | ||
op[1] = schema.cast(op[1])[0]; | ||
val = atomics[op]; | ||
obj = delta[op] = delta[op] || {}; | ||
if (op === '$pull' || op === '$push') { | ||
if (val.constructor !== Object) { | ||
val = schema.cast(val)[0]; | ||
} | ||
} | ||
obj[type._path] = op[1].toObject | ||
? op[1].toObject() // If the value is an array | ||
: Array.isArray(op[1]) | ||
? op[1].map( function (mem) { | ||
obj[type._path] = val.toObject | ||
? val.toObject() // If the value is an array | ||
: Array.isArray(val) | ||
? val.map( function (mem) { | ||
return mem.toObject | ||
@@ -149,6 +128,6 @@ ? mem.toObject() | ||
}) | ||
: op[1].valueOf | ||
? op[1].valueOf() // Numbers | ||
: op[1]; | ||
}); | ||
: val.valueOf | ||
? val.valueOf() // Numbers | ||
: val; | ||
} | ||
} else { | ||
@@ -155,0 +134,0 @@ // normalize MongooseArray or MongooseNumber |
@@ -24,3 +24,3 @@ | ||
arr.__proto__ = MongooseArray.prototype; | ||
arr._atomics = []; | ||
arr._atomics = {}; | ||
arr.validators = []; | ||
@@ -76,4 +76,12 @@ arr._path = path; | ||
MongooseArray.prototype._markModified = function () { | ||
if (this._parent) | ||
this._parent.activePaths.modify(this._path); | ||
var parent = this._parent; | ||
if (parent) { | ||
if (parent.markModified) { | ||
// If we have an embedded document | ||
parent.markModified(); | ||
} else { | ||
// If we don't have a top level document | ||
parent.activePaths.modify(this._path); | ||
} | ||
} | ||
return this; | ||
@@ -89,4 +97,10 @@ }; | ||
MongooseArray.prototype._registerAtomic = function (op) { | ||
this._atomics.push(op); | ||
MongooseArray.prototype._registerAtomic = function (op, val) { | ||
var atomics = this._atomics | ||
if (op === '$pullAll' || op === '$pushAll') { | ||
atomics[op] || (atomics[op] = []); | ||
atomics[op] = atomics[op].concat(val); | ||
} else { | ||
atomics[op] = val; | ||
} | ||
this._markModified(); | ||
@@ -104,3 +118,3 @@ return this; | ||
MongooseArray.prototype.__defineGetter__('doAtomics', function () { | ||
return this._atomics.length; | ||
return Object.keys(this._atomics).length; | ||
}); | ||
@@ -122,6 +136,5 @@ | ||
if (1 === values.length) | ||
this._registerAtomic(['$push', values[0]]); | ||
else | ||
this._registerAtomic(['$pushAll', values]); | ||
// $pushAll might be fibbed (could be $push). But it makes it easier to | ||
// handle what could have been $push, $pushAll combos | ||
this._registerAtomic('$pushAll', values); | ||
@@ -159,3 +172,3 @@ return ret; | ||
// make sure we access the casted elements | ||
this._registerAtomic(['$pushAll', this.slice(length) ]); | ||
this._registerAtomic('$pushAll', this.slice(length)); | ||
return this; | ||
@@ -171,3 +184,3 @@ }; | ||
MongooseArray.prototype.$pop = function () { | ||
this._registerAtomic(['$pop', '1']); | ||
this._registerAtomic('$pop', '1'); | ||
return this.pop(); | ||
@@ -183,3 +196,3 @@ }; | ||
MongooseArray.prototype.$shift = function () { | ||
this._registerAtomic(['$shift', '-1']); | ||
this._registerAtomic('$shift', '-1'); | ||
return this.shift(); | ||
@@ -227,14 +240,6 @@ }; | ||
} | ||
if (1 === values.length) { | ||
if (values[0] instanceof EmbeddedDocument) { | ||
this._registerAtomic(['$pull', {_id: values[0]._id}]); | ||
} else { | ||
this._registerAtomic(['$pull', values[0]]); | ||
} | ||
if (values[0] instanceof EmbeddedDocument) { | ||
this._registerAtomic('$pullAll', values.map( function (v) { return {_id: v._id}; } )); | ||
} else { | ||
if (values[0] instanceof EmbeddedDocument) { | ||
this._registerAtomic(['$pullAll', values.map( function (v) { return {_id: v._id}; } )]); | ||
} else { | ||
this._registerAtomic(['$pullAll', values]); | ||
} | ||
this._registerAtomic('$pullAll', values); | ||
} | ||
@@ -251,3 +256,3 @@ return this; | ||
MongooseArray.prototype.$pullAll = function (values) { | ||
if (values && values.length) | ||
if (values && values.length) { | ||
var oldArr = this._parent.get(this._path) | ||
@@ -263,3 +268,4 @@ , i = oldArr.length, mem; | ||
} | ||
this._registerAtomic(['$pullAll', values]); | ||
this._registerAtomic('$pullAll', values); | ||
} | ||
return this; | ||
@@ -266,0 +272,0 @@ }; |
@@ -17,3 +17,3 @@ | ||
number.__proto__ = MongooseNumber.prototype; | ||
number._atomics = []; | ||
number._atomics = {}; | ||
number._path = path; | ||
@@ -41,3 +41,3 @@ number._parent = doc; | ||
this._parent.setValue(this._path, schema.cast(this + value)); | ||
this._parent.getValue(this._path)._atomics = [['$inc', value || 1]]; | ||
this._parent.getValue(this._path)._atomics['$inc'] = value || 1; | ||
this._parent.activePaths.modify(this._path); | ||
@@ -55,3 +55,3 @@ return this; | ||
MongooseNumber.prototype.__defineGetter__('doAtomics', function () { | ||
return this._atomics.length; | ||
return Object.keys(this._atomics).length; | ||
}); | ||
@@ -58,0 +58,0 @@ |
{ | ||
"name": "mongoose" | ||
, "description": "Mongoose MongoDB ORM" | ||
, "version": "1.0.13" | ||
, "version": "1.0.14" | ||
, "author": "Guillermo Rauch <guillermo@learnboost.com>" | ||
@@ -6,0 +6,0 @@ , "keywords": ["mongodb", "mongoose", "orm", "data", "datastore", "nosql"] |
@@ -1272,2 +1272,40 @@ | ||
'test doubly nested array saving and loading': function(){ | ||
var Inner = new Schema({ | ||
arr: [Number] | ||
}); | ||
var Outer = new Schema({ | ||
inner: [Inner] | ||
}); | ||
mongoose.model('Outer', Outer); | ||
var db = start(); | ||
var Outer = db.model('Outer', 'arr_test_' + random()); | ||
var outer = new Outer(); | ||
outer.inner.push({}); | ||
outer.save(function(err) { | ||
should.strictEqual(err, null); | ||
outer.get('_id').should.be.an.instanceof(DocumentObjectId); | ||
Outer.findById(outer.get('_id'), function(err, found) { | ||
should.strictEqual(err, null); | ||
should.equal(1, found.inner.length); | ||
found.inner[0].arr.push(5); | ||
found.save(function(err) { | ||
should.strictEqual(err, null); | ||
found.get('_id').should.be.an.instanceof(DocumentObjectId); | ||
Outer.findById(found.get('_id'), function(err, found2) { | ||
should.strictEqual(err, null); | ||
should.equal(1, found2.inner.length); | ||
should.equal(1, found2.inner[0].arr.length); | ||
should.equal(5, found2.inner[0].arr[0]); | ||
db.close(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}, | ||
'test updating multiple Number $pushes as a single $pushAll': function () { | ||
@@ -1274,0 +1312,0 @@ var db = start() |
@@ -21,5 +21,5 @@ | ||
Array.isArray(a).should.be.true; | ||
Array.isArray(a._atomics).should.be.true; | ||
(a._atomics.constructor).should.eql(Object); | ||
} | ||
}; |
@@ -22,5 +22,5 @@ | ||
Array.isArray(a._atomics).should.be.true; | ||
(a._atomics.constructor).should.eql(Object); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1406229
24864