From 7ca9c8fe0dac3b9077bcbaa218e238b007a5de64 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Thu, 2 May 2013 14:33:09 +0200 Subject: [PATCH] Update function doesnt swallow _id anymore --- lib/customUtils.js | 25 ++++++++++++++++++++++ lib/datastore.js | 13 +++++++++++- test/db.test.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/lib/customUtils.js b/lib/customUtils.js index 2a0a40a..b5f3057 100644 --- a/lib/customUtils.js +++ b/lib/customUtils.js @@ -34,6 +34,31 @@ function uid (len) { } +/** + * Deep copy an DB object + * TODO: Put in serialization/deserialization and tackle all cases + */ +function deepCopy (obj) { + var res; + + if (typeof obj === 'boolean' || typeof obj === 'number' || typeof obj === 'string') { + return obj; + } + + if (typeof obj === 'object') { + res = {}; + Object.keys(obj).forEach(function (k) { + res[k] = deepCopy(obj[k]); + }); + return res; + } + + return undefined; // For now everything else is undefined. We should probably throw an error instead +} + + + module.exports.ensureDirectoryExists = ensureDirectoryExists; module.exports.uid = uid; +module.exports.deepCopy = deepCopy; diff --git a/lib/datastore.js b/lib/datastore.js index 7ee6407..f0518e2 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -181,6 +181,17 @@ Datastore.prototype.persistWholeDatabase = function (data, cb) { }; +/** + * Modify an object according to the updateQuery + * For now the updateQuery only replaces the object + */ +Datastore.modify = function (obj, updateQuery) { + updateQuery = customUtils.deepCopy(updateQuery); + updateQuery._id = obj._id; + return updateQuery; +}; + + /** * Update all docs matching query * For now, very naive implementation (recalculating the whole database) @@ -204,7 +215,7 @@ Datastore.prototype.update = function (query, newDoc, options, cb) { self.data.forEach(function (d) { if (Datastore.match(d, query) && (multi || numReplaced === 0)) { numReplaced += 1; - newData.push(newDoc); + newData.push(Datastore.modify(d, newDoc)); } else { newData.push(d); } diff --git a/test/db.test.js b/test/db.test.js index 3e3cd9d..ced68e4 100644 --- a/test/db.test.js +++ b/test/db.test.js @@ -228,6 +228,58 @@ describe('Database', function () { ], done); }); + it("Can update multiple documents matching the query", function (done) { + var d = new Datastore(testDb) + , id1, id2, id3; + + async.waterfall([ + function (cb) { + d.loadDatabase(function (err) { + d.insert({ somedata: 'ok' }, function (err, doc1) { + id1 = doc1._id; + d.insert({ somedata: 'again', plus: 'additional data' }, function (err, doc2) { + id2 = doc2._id; + d.insert({ somedata: 'again' }, function (err, doc3) { + id3 = doc3._id; + return cb(err); + }); + }); + }); + }); + } + , function (cb) { // Test with query that doesn't match anything + d.update({ somedata: 'again' }, { newDoc: 'yes' }, { multi: true }, function (err, n) { + assert.isNull(err); + n.should.equal(2); + + d.find({}, function (err, docs) { + var doc1 = _.find(docs, function (d) { return d._id === id1; }) + , doc2 = _.find(docs, function (d) { return d._id === id2; }) + , doc3 = _.find(docs, function (d) { return d._id === id3; }) + ; + + docs.length.should.equal(3); + + Object.keys(doc1).length.should.equal(2); + doc1.somedata.should.equal('ok'); + doc1._id.should.equal(id1); + + Object.keys(doc2).length.should.equal(2); + doc2.newDoc.should.equal('yes'); + doc2._id.should.equal(id2); + + Object.keys(doc3).length.should.equal(2); + doc3.newDoc.should.equal('yes'); + doc3._id.should.equal(id3); + + return cb(); + }); + }); + } + ], done); + }); + + }); // ==== End of 'Update' ==== //