Roll back an insert if a unique is violated on a key array element

pull/2/head
Louis Chatriot 11 years ago
parent f48a1565bc
commit 856f214175
  1. 27
      lib/indexes.js
  2. 23
      test/indexes.test.js

@ -62,7 +62,9 @@ Index.prototype.reset = function (newData) {
* O(log(n)) * O(log(n))
*/ */
Index.prototype.insert = function (doc) { Index.prototype.insert = function (doc) {
var key, self = this; var key, self = this
, keys, i, failingI, error
;
if (util.isArray(doc)) { this.insertMultipleDocs(doc); return; } if (util.isArray(doc)) { this.insertMultipleDocs(doc); return; }
@ -74,9 +76,26 @@ Index.prototype.insert = function (doc) {
if (!util.isArray(key)) { if (!util.isArray(key)) {
this.tree.insert(key, doc); this.tree.insert(key, doc);
} else { } else {
_.uniq(key, projectForUnique).forEach(function (_key) { // If an insert fails due to a unique constraint, roll back all inserts before it
self.tree.insert(_key, doc); keys = _.uniq(key, projectForUnique);
});
for (i = 0; i < keys.length; i += 1) {
try {
this.tree.insert(keys[i], doc);
} catch (e) {
error = e;
failingI = i;
break;
}
}
if (error) {
for (i = 0; i < failingI; i += 1) {
this.tree.delete(keys[i], doc);
}
throw error;
}
} }
}; };

@ -177,7 +177,7 @@ describe('Indexes', function () {
(function () { idx.insert(obj2); }).should.throw(); (function () { idx.insert(obj2); }).should.throw();
}); });
it('When removing a document, remove it from the index at all array elements', function () { it('When removing a document, remove it from the index at all unique array elements', function () {
var obj = { tf: ['aa', 'aa'], really: 'yeah' } var obj = { tf: ['aa', 'aa'], really: 'yeah' }
, obj2 = { tf: ['cc', 'aa', 'cc'], yes: 'indeed' } , obj2 = { tf: ['cc', 'aa', 'cc'], yes: 'indeed' }
, idx = new Index({ fieldName: 'tf' }) , idx = new Index({ fieldName: 'tf' })
@ -197,6 +197,27 @@ describe('Indexes', function () {
idx.getMatching('cc').length.should.equal(0); idx.getMatching('cc').length.should.equal(0);
}); });
it('If a unique constraint is violated when inserting an array key, roll back all inserts before the key', function () {
var obj = { tf: ['aa', 'bb'], really: 'yeah' }
, obj2 = { tf: ['cc', 'dd', 'aa'], yes: 'indeed' }
, idx = new Index({ fieldName: 'tf', unique: true })
;
idx.insert(obj);
idx.getAll().length.should.equal(2);
idx.getMatching('aa').length.should.equal(1);
idx.getMatching('bb').length.should.equal(1);
idx.getMatching('cc').length.should.equal(0);
idx.getMatching('dd').length.should.equal(0);
(function () { idx.insert(obj2); }).should.throw();
idx.getAll().length.should.equal(2);
idx.getMatching('aa').length.should.equal(1);
idx.getMatching('bb').length.should.equal(1);
idx.getMatching('cc').length.should.equal(0);
idx.getMatching('dd').length.should.equal(0);
});
}); // ==== End of 'Array fields' ==== // }); // ==== End of 'Array fields' ==== //
}); // ==== End of 'Insertion' ==== // }); // ==== End of 'Insertion' ==== //

Loading…
Cancel
Save