From 9c42221f959ed747de8233dd05bce8ba1df9f0d0 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Thu, 30 May 2013 15:02:45 +0200 Subject: [PATCH] Database loading doens't work if a unique constraint is violated --- lib/datastore.js | 26 +++++++++++++------ test/db.test.js | 65 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 12 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index d536fa8..cee6f09 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -165,15 +165,25 @@ Datastore.prototype._loadDatabase = function (cb) { self.data = []; self.datafileSize = 0; fs.writeFile(self.filename, '', 'utf8', function (err) { return callback(err); }); - } else { - fs.readFile(self.filename, 'utf8', function (err, rawData) { - if (err) { return callback(err); } - self.data = Datastore.treatRawData(rawData); - self.datafileSize = self.data.length; - self.resetIndexes(self.data); - self.persistCachedDatabase(callback); - }); + return; } + + fs.readFile(self.filename, 'utf8', function (err, rawData) { + if (err) { return callback(err); } + self.data = Datastore.treatRawData(rawData); + + try { + self.resetIndexes(self.data); + } catch (e) { + self.resetIndexes(); // Rollback any index which didn't fail + self.datafileSize = 0; + self.data = []; + return callback(e); + } + + self.datafileSize = self.data.length; + self.persistCachedDatabase(callback); + }); }); }); }; diff --git a/test/db.test.js b/test/db.test.js index 073549d..3f18589 100644 --- a/test/db.test.js +++ b/test/db.test.js @@ -1220,12 +1220,69 @@ describe('Database', function () { }); }); - it.skip('Can initialize multiple indexes', function (done) { - done(); + it('Can initialize multiple indexes', function (done) { + var now = new Date() + , rawData = model.serialize({ _id: "aaa", z: "1", a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: "bbb", z: "2", a: 'world' }) + '\n' + + model.serialize({ _id: "ccc", z: "3", a: { today: now } }) + ; + + d.data.length.should.equal(0); + d.datafileSize.should.equal(0); + + d.ensureIndex({ fieldName: 'z' }); + d.ensureIndex({ fieldName: 'a' }); + d.indexes.a.tree.getNumberOfKeys().should.equal(0); + d.indexes.z.tree.getNumberOfKeys().should.equal(0); + + fs.writeFile(testDb, rawData, 'utf8', function () { + d.loadDatabase(function () { + d.data.length.should.equal(3); + d.datafileSize.should.equal(3); + + d.indexes.z.tree.getNumberOfKeys().should.equal(3); + d.indexes.z.tree.search('1')[0].should.equal(d.data[0]); + d.indexes.z.tree.search('2')[0].should.equal(d.data[1]); + d.indexes.z.tree.search('3')[0].should.equal(d.data[2]); + + d.indexes.a.tree.getNumberOfKeys().should.equal(3); + d.indexes.a.tree.search(2)[0].should.equal(d.data[0]); + d.indexes.a.tree.search('world')[0].should.equal(d.data[1]); + d.indexes.a.tree.search({ today: now })[0].should.equal(d.data[2]); + + done(); + }); + }); }); - it.skip('If a unique constraint is not respected, database loading will not work and no data will be inserted', function (done) { - done(); + it('If a unique constraint is not respected, database loading will not work and no data will be inserted', function (done) { + var now = new Date() + , rawData = model.serialize({ _id: "aaa", z: "1", a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: "bbb", z: "2", a: 'world' }) + '\n' + + model.serialize({ _id: "ccc", z: "1", a: { today: now } }) + ; + + d.data.length.should.equal(0); + d.datafileSize.should.equal(0); + + d.ensureIndex({ fieldName: 'z', unique: true }); + d.indexes.z.tree.getNumberOfKeys().should.equal(0); + + fs.writeFile(testDb, rawData, 'utf8', function () { + d.loadDatabase(function (err) { + err.errorType.should.equal('uniqueViolated'); + err.key.should.equal("1"); + d.data.length.should.equal(0); + d.datafileSize.should.equal(0); + + d.indexes.z.tree.getNumberOfKeys().should.equal(0); + + done(); + }); + }); + }); + + it.skip('If a unique constraint is not respected, ensureIndex will return an error', function (done) { }); }); // ==== End of 'ensureIndex' ==== //