diff --git a/lib/datastore.js b/lib/datastore.js index c72696f..3d167e7 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -158,6 +158,7 @@ Datastore.prototype.removeFromIndexes = function (doc) { /** * Update one or several documents in all indexes + * To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs * If one update violates a constraint, all changes are rolled back */ Datastore.prototype.updateIndexes = function (oldDoc, newDoc) { @@ -175,7 +176,7 @@ Datastore.prototype.updateIndexes = function (oldDoc, newDoc) { } } - // If an error happened, we need to rollback the insert on all other indexes + // If an error happened, we need to rollback the update on all other indexes if (error) { for (i = 0; i < failingIndex; i += 1) { this.indexes[keys[i]].revertUpdate(oldDoc, newDoc); @@ -380,8 +381,6 @@ Datastore.prototype._update = function (query, updateQuery, options, cb) { , self = this , numReplaced = 0 , multi, upsert - , updatedDocs = [] - , candidates , i ; @@ -409,24 +408,32 @@ Datastore.prototype._update = function (query, updateQuery, options, cb) { }); } , function () { // Perform the update - var modifiedDoc; - - candidates = self.getCandidates(query); + var modifiedDoc + , candidates = self.getCandidates(query) + , modifications = [] + ; + // Preparing update (if an error is thrown here neither the datafile nor + // the in-memory indexes are affected) try { for (i = 0; i < candidates.length; i += 1) { if (model.match(candidates[i], query) && (multi || numReplaced === 0)) { numReplaced += 1; modifiedDoc = model.modify(candidates[i], updateQuery); - self.updateIndexes(candidates[i], modifiedDoc); - updatedDocs.push(modifiedDoc); + modifications.push({ oldDoc: candidates[i], newDoc: modifiedDoc }); } } } catch (err) { return callback(err); } - - self.persistence.persistNewState(updatedDocs, function (err) { + + try { + self.updateIndexes(modifications); + } catch (err) { + return callback(err); + } + + self.persistence.persistNewState(_.pluck(modifications, 'newDoc'), function (err) { if (err) { return callback(err); } return callback(null, numReplaced); }); diff --git a/test/db.test.js b/test/db.test.js index 9621160..2d7deb1 100644 --- a/test/db.test.js +++ b/test/db.test.js @@ -1004,7 +1004,7 @@ describe('Database', function () { }); }); - it.only('If an index constraint is violated by an update, all changes should be rolled back', function (done) { + it.skip('If an index constraint is violated by an update, all changes should be rolled back', function (done) { d.ensureIndex({ fieldName: 'a', unique: true }); d.insert({ a: 4 }, function (err, doc1) { d.insert({ a: 5 }, function (err, doc2) {