Loading the database-type tests pas

pull/2/head
Louis Chatriot 12 years ago
parent ae0937520b
commit 6007248d84
  1. 45
      lib/datastore.js
  2. 8
      test/db.test.js

@ -15,7 +15,6 @@ var fs = require('fs')
*/ */
function Datastore (filename) { function Datastore (filename) {
this.filename = filename; this.filename = filename;
this.data = [];
this.executor = new Executor(); this.executor = new Executor();
// We keep internally the number of lines in the datafile // We keep internally the number of lines in the datafile
@ -26,10 +25,18 @@ function Datastore (filename) {
// _id is always indexed and since _ids are generated randomly the underlying // _id is always indexed and since _ids are generated randomly the underlying
// binary is always well-balanced // binary is always well-balanced
this.indexes = {}; this.indexes = {};
this.ensureIndex({ fieldName: '_id', unique: true }); this.indexes._id = new Index({ fieldName: '_id', unique: true });
} }
/**
* Get an array of all the data in the database
*/
Datastore.prototype.getAllData = function () {
return this.indexes._id.getAll();
};
/** /**
* Reset all currently defined indexes * Reset all currently defined indexes
*/ */
@ -63,7 +70,7 @@ Datastore.prototype.ensureIndex = function (options, cb) {
this.indexes[options.fieldName] = new Index(options); this.indexes[options.fieldName] = new Index(options);
try { try {
this.indexes[options.fieldName].insert(this.data); this.indexes[options.fieldName].insert(this.getAllData());
} catch (e) { } catch (e) {
delete this.indexes[options.fieldName]; delete this.indexes[options.fieldName];
return callback(e); return callback(e);
@ -138,7 +145,7 @@ Datastore.prototype.getCandidates = function (query) {
var indexNames = Object.keys(this.indexes) var indexNames = Object.keys(this.indexes)
, usableQueryKeys; , usableQueryKeys;
if (indexNames.length === 0) { return this.data; } // No index defined, no specific candidate if (indexNames.length <= 1) { return this.getAllData(); } // No index defined (except _id), no specific candidate
// Usable query keys are the ones corresponding to a basic query (no use of $operators or arrays) // Usable query keys are the ones corresponding to a basic query (no use of $operators or arrays)
usableQueryKeys = []; usableQueryKeys = [];
@ -153,7 +160,7 @@ Datastore.prototype.getCandidates = function (query) {
if (usableQueryKeys.length > 0) { if (usableQueryKeys.length > 0) {
return this.indexes[usableQueryKeys[0]].getMatching(query[usableQueryKeys[0]]); return this.indexes[usableQueryKeys[0]].getMatching(query[usableQueryKeys[0]]);
} else { } else {
return this.data; return this.getAllData();
} }
}; };
@ -175,7 +182,6 @@ Datastore.prototype._loadDatabase = function (cb) {
customUtils.ensureDirectoryExists(path.dirname(self.filename), function (err) { customUtils.ensureDirectoryExists(path.dirname(self.filename), function (err) {
fs.exists(self.filename, function (exists) { fs.exists(self.filename, function (exists) {
if (!exists) { if (!exists) {
self.data = [];
self.datafileSize = 0; self.datafileSize = 0;
fs.writeFile(self.filename, '', 'utf8', function (err) { return callback(err); }); fs.writeFile(self.filename, '', 'utf8', function (err) { return callback(err); });
return; return;
@ -183,18 +189,17 @@ Datastore.prototype._loadDatabase = function (cb) {
fs.readFile(self.filename, 'utf8', function (err, rawData) { fs.readFile(self.filename, 'utf8', function (err, rawData) {
if (err) { return callback(err); } if (err) { return callback(err); }
self.data = Datastore.treatRawData(rawData); var treatedData = Datastore.treatRawData(rawData);
try { try {
self.resetIndexes(self.data); self.resetIndexes(treatedData);
} catch (e) { } catch (e) {
self.resetIndexes(); // Rollback any index which didn't fail self.resetIndexes(); // Rollback any index which didn't fail
self.datafileSize = 0; self.datafileSize = 0;
self.data = [];
return callback(e); return callback(e);
} }
self.datafileSize = self.data.length; self.datafileSize = treatedData.length;
self.persistCachedDatabase(callback); self.persistCachedDatabase(callback);
}); });
}); });
@ -251,7 +256,7 @@ Datastore.prototype.persistCachedDatabase = function (cb) {
, toPersist = '' , toPersist = ''
; ;
this.data.forEach(function (doc) { this.getAllData().forEach(function (doc) {
toPersist += model.serialize(doc) + '\n'; toPersist += model.serialize(doc) + '\n';
}); });
@ -291,9 +296,8 @@ Datastore.prototype._insert = function (newDoc, cb) {
fs.appendFile(self.filename, persistableNewDoc + '\n', 'utf8', function (err) { fs.appendFile(self.filename, persistableNewDoc + '\n', 'utf8', function (err) {
if (err) { return callback(err); } if (err) { return callback(err); }
self.data.push(insertedDoc);
self.datafileSize += 1; self.datafileSize += 1;
return callback(null, model.deepCopy(insertedDoc)); return callback(null, model.deepCopy(insertedDoc)); // CHANGE
}); });
}; };
@ -466,10 +470,8 @@ Datastore.prototype.update = function () {
Datastore.prototype._remove = function (query, options, cb) { Datastore.prototype._remove = function (query, options, cb) {
var callback var callback
, self = this , self = this
//, candidates = this.getCandidates(query)
, numRemoved = 0 , numRemoved = 0
, multi , multi
, newData = []
, removedDocs = [] , removedDocs = []
; ;
@ -477,23 +479,22 @@ Datastore.prototype._remove = function (query, options, cb) {
callback = cb || function () {}; callback = cb || function () {};
multi = options.multi !== undefined ? options.multi : false; multi = options.multi !== undefined ? options.multi : false;
// CHANGE
try { try {
self.data.forEach(function (d) { self.getAllData().forEach(function (d) { // CHANGE
if (model.match(d, query) && (multi || numRemoved === 0)) { if (model.match(d, query) && (multi || numRemoved === 0)) {
numRemoved += 1; numRemoved += 1;
removedDocs.push({ $$deleted: true, _id: d._id }); removedDocs.push({ $$deleted: true, _id: d._id });
self.removeFromIndexes(d); self.removeFromIndexes(d);
} else {
newData.push(d);
} }
}); });
} catch (err) { } catch (err) { return callback(err); }
return callback(err);
}
self.persistNewState(removedDocs, function (err) { self.persistNewState(removedDocs, function (err) {
if (err) { return callback(err); } if (err) { return callback(err); }
self.data = newData;
return callback(null, numRemoved); return callback(null, numRemoved);
}); });
}; };

@ -31,7 +31,7 @@ describe('Database', function () {
d.loadDatabase(function (err) { d.loadDatabase(function (err) {
assert.isNull(err); assert.isNull(err);
d.datafileSize.should.equal(0); d.datafileSize.should.equal(0);
d.data.length.should.equal(0); d.getAllData().length.should.equal(0);
return cb(); return cb();
}); });
} }
@ -40,7 +40,7 @@ describe('Database', function () {
}); });
describe('Loading the database data from file and persistence', function () { describe.only('Loading the database data from file and persistence', function () {
it('Every line represents a document', function () { it('Every line represents a document', function () {
var now = new Date() var now = new Date()
@ -163,12 +163,12 @@ describe('Database', function () {
model.serialize({ _id: "3", nested: { today: now } }) model.serialize({ _id: "3", nested: { today: now } })
; ;
d.data.length.should.equal(0); d.getAllData().length.should.equal(0);
d.datafileSize.should.equal(0); d.datafileSize.should.equal(0);
fs.writeFile(testDb, rawData, 'utf8', function () { fs.writeFile(testDb, rawData, 'utf8', function () {
d.loadDatabase(function () { d.loadDatabase(function () {
d.data.length.should.equal(3); d.getAllData().length.should.equal(3);
d.datafileSize.should.equal(3); d.datafileSize.should.equal(3);
d.find({}, function (err, docs) { d.find({}, function (err, docs) {

Loading…
Cancel
Save