Check that if one hook is defined the other is too

pull/2/head
Louis Chatriot 10 years ago
parent 0597a4e47a
commit 3e67adc2bb
  1. 8
      lib/persistence.js
  2. 260
      test/persistence.test.js

@ -34,7 +34,13 @@ function Persistence (options) {
} }
} }
// After serialization and before deserialization hooks // After serialization and before deserialization hooks with some basic sanity checks
if (options.afterSerialization && !options.beforeDeserialization) {
throw "Serialization hook defined but deserialization hook undefined, cautiously refusing to start NeDB";
}
if (!options.afterSerialization && options.beforeDeserialization) {
throw "Serialization hook undefined but deserialization hook defined, cautiously refusing to start NeDB";
}
this.afterSerialization = options.afterSerialization || function (s) { return s; }; this.afterSerialization = options.afterSerialization || function (s) { return s; };
this.beforeDeserialization = options.beforeDeserialization || function (s) { return s; }; this.beforeDeserialization = options.beforeDeserialization || function (s) { return s; };

@ -268,67 +268,61 @@ describe('Persistence', function () {
}); });
}); });
describe('Data can be persisted using serialization hooks', function () { describe.only('Data can be persisted using serialization hooks', function () {
var as = function (s) { return "before_" + s + "_after"; } var as = function (s) { return "before_" + s + "_after"; }
, bd = function (s) { return s.substring(7, s.length - 6); } , bd = function (s) { return s.substring(7, s.length - 6); }
it("Declaring only one hook will throw an exception to prevent data loss", function (done) {
var hookTestFilename = 'workspace/hookTest.db'
Persistence.ensureFileDoesntExist(hookTestFilename, function () {
(function () {
new Datastore({ filename: hookTestFilename, autoload: true
, afterSerialization: as
});
}).should.throw();
(function () {
new Datastore({ filename: hookTestFilename, autoload: true
, beforeDeserialization: bd
});
}).should.throw();
done();
});
});
it("A serialization hook can be used to transform data before writing new state to disk", function (done) { it("A serialization hook can be used to transform data before writing new state to disk", function (done) {
var hookTestFilename = 'workspace/hookTest.db' var hookTestFilename = 'workspace/hookTest.db'
fs.unlinkSync(hookTestFilename); Persistence.ensureFileDoesntExist(hookTestFilename, function () {
var d = new Datastore({ filename: hookTestFilename, autoload: true
var d = new Datastore({ filename: hookTestFilename, autoload: true , afterSerialization: as
, afterSerialization: as , beforeDeserialization: bd
, beforeDeserialization: bd })
})
;
d.insert({ hello: "world" }, function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n')
, doc0 = bd(data[0])
; ;
data.length.should.equal(2); d.insert({ hello: "world" }, function () {
data[0].substring(0, 7).should.equal('before_');
data[0].substring(data[0].length - 6).should.equal('_after');
doc0 = model.deserialize(doc0);
Object.keys(doc0).length.should.equal(2);
doc0.hello.should.equal('world');
d.insert({ p: 'Mars' }, function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8') var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n') , data = _data.split('\n')
, doc0 = bd(data[0]) , doc0 = bd(data[0])
, doc1 = bd(data[1])
; ;
data.length.should.equal(3); data.length.should.equal(2);
data[0].substring(0, 7).should.equal('before_'); data[0].substring(0, 7).should.equal('before_');
data[0].substring(data[0].length - 6).should.equal('_after'); data[0].substring(data[0].length - 6).should.equal('_after');
data[1].substring(0, 7).should.equal('before_');
data[1].substring(data[1].length - 6).should.equal('_after');
doc0 = model.deserialize(doc0); doc0 = model.deserialize(doc0);
Object.keys(doc0).length.should.equal(2); Object.keys(doc0).length.should.equal(2);
doc0.hello.should.equal('world'); doc0.hello.should.equal('world');
doc1 = model.deserialize(doc1); d.insert({ p: 'Mars' }, function () {
Object.keys(doc1).length.should.equal(2);
doc1.p.should.equal('Mars');
d.ensureIndex({ fieldName: 'idefix' }, function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8') var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n') , data = _data.split('\n')
, doc0 = bd(data[0]) , doc0 = bd(data[0])
, doc1 = bd(data[1]) , doc1 = bd(data[1])
, idx = bd(data[2])
; ;
data.length.should.equal(4); data.length.should.equal(3);
data[0].substring(0, 7).should.equal('before_'); data[0].substring(0, 7).should.equal('before_');
data[0].substring(data[0].length - 6).should.equal('_after'); data[0].substring(data[0].length - 6).should.equal('_after');
@ -342,72 +336,96 @@ describe('Persistence', function () {
doc1 = model.deserialize(doc1); doc1 = model.deserialize(doc1);
Object.keys(doc1).length.should.equal(2); Object.keys(doc1).length.should.equal(2);
doc1.p.should.equal('Mars'); doc1.p.should.equal('Mars');
idx = model.deserialize(idx); d.ensureIndex({ fieldName: 'idefix' }, function () {
assert.deepEqual(idx, { '$$indexCreated': { fieldName: 'idefix' } }); var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n')
, doc0 = bd(data[0])
, doc1 = bd(data[1])
, idx = bd(data[2])
;
data.length.should.equal(4);
data[0].substring(0, 7).should.equal('before_');
data[0].substring(data[0].length - 6).should.equal('_after');
data[1].substring(0, 7).should.equal('before_');
data[1].substring(data[1].length - 6).should.equal('_after');
doc0 = model.deserialize(doc0);
Object.keys(doc0).length.should.equal(2);
doc0.hello.should.equal('world');
doc1 = model.deserialize(doc1);
Object.keys(doc1).length.should.equal(2);
doc1.p.should.equal('Mars');
done(); idx = model.deserialize(idx);
}); assert.deepEqual(idx, { '$$indexCreated': { fieldName: 'idefix' } });
done();
});
});
}); });
}); });
}); });
it("Use serialization hook when persisting cached database or compacting", function (done) { it("Use serialization hook when persisting cached database or compacting", function (done) {
var hookTestFilename = 'workspace/hookTest.db' var hookTestFilename = 'workspace/hookTest.db'
fs.unlinkSync(hookTestFilename); Persistence.ensureFileDoesntExist(hookTestFilename, function () {
var d = new Datastore({ filename: hookTestFilename, autoload: true
var d = new Datastore({ filename: hookTestFilename, autoload: true , afterSerialization: as
, afterSerialization: as , beforeDeserialization: bd
, beforeDeserialization: bd })
}) ;
;
d.insert({ hello: "world" }, function () {
d.update({ hello: "world" }, { $set: { hello: "earth" } }, {}, function () {
d.ensureIndex({ fieldName: 'idefix' }, function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n')
, doc0 = bd(data[0])
, doc1 = bd(data[1])
, idx = bd(data[2])
, _id
;
data.length.should.equal(4);
doc0 = model.deserialize(doc0);
Object.keys(doc0).length.should.equal(2);
doc0.hello.should.equal('world');
doc1 = model.deserialize(doc1);
Object.keys(doc1).length.should.equal(2);
doc1.hello.should.equal('earth');
doc0._id.should.equal(doc1._id);
_id = doc0._id;
idx = model.deserialize(idx);
assert.deepEqual(idx, { '$$indexCreated': { fieldName: 'idefix' } });
d.persistence.persistCachedDatabase(function () { d.insert({ hello: "world" }, function () {
d.update({ hello: "world" }, { $set: { hello: "earth" } }, {}, function () {
d.ensureIndex({ fieldName: 'idefix' }, function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8') var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n') , data = _data.split('\n')
, doc0 = bd(data[0]) , doc0 = bd(data[0])
, idx = bd(data[1]) , doc1 = bd(data[1])
, idx = bd(data[2])
, _id
; ;
data.length.should.equal(3); data.length.should.equal(4);
doc0 = model.deserialize(doc0); doc0 = model.deserialize(doc0);
Object.keys(doc0).length.should.equal(2); Object.keys(doc0).length.should.equal(2);
doc0.hello.should.equal('earth'); doc0.hello.should.equal('world');
doc1 = model.deserialize(doc1);
Object.keys(doc1).length.should.equal(2);
doc1.hello.should.equal('earth');
doc0._id.should.equal(_id); doc0._id.should.equal(doc1._id);
_id = doc0._id;
idx = model.deserialize(idx); idx = model.deserialize(idx);
assert.deepEqual(idx, { '$$indexCreated': { fieldName: 'idefix', unique: false, sparse: false } }); assert.deepEqual(idx, { '$$indexCreated': { fieldName: 'idefix' } });
done(); d.persistence.persistCachedDatabase(function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n')
, doc0 = bd(data[0])
, idx = bd(data[1])
;
data.length.should.equal(3);
doc0 = model.deserialize(doc0);
Object.keys(doc0).length.should.equal(2);
doc0.hello.should.equal('earth');
doc0._id.should.equal(_id);
idx = model.deserialize(idx);
assert.deepEqual(idx, { '$$indexCreated': { fieldName: 'idefix', unique: false, sparse: false } });
done();
});
}); });
}); });
}); });
@ -416,47 +434,47 @@ describe('Persistence', function () {
it("Deserialization hook is correctly used when loading data", function (done) { it("Deserialization hook is correctly used when loading data", function (done) {
var hookTestFilename = 'workspace/hookTest.db' var hookTestFilename = 'workspace/hookTest.db'
fs.unlinkSync(hookTestFilename); Persistence.ensureFileDoesntExist(hookTestFilename, function () {
var d = new Datastore({ filename: hookTestFilename, autoload: true
var d = new Datastore({ filename: hookTestFilename, autoload: true , afterSerialization: as
, afterSerialization: as , beforeDeserialization: bd
, beforeDeserialization: bd })
}) ;
;
d.insert({ hello: "world" }, function (err, doc) {
var _id = doc._id;
d.insert({ yo: "ya" }, function () {
d.update({ hello: "world" }, { $set: { hello: "earth" } }, {}, function () {
d.remove({ yo: "ya" }, {}, function () {
d.ensureIndex({ fieldName: 'idefix' }, function () {
var _data = fs.readFileSync(hookTestFilename, 'utf8')
, data = _data.split('\n')
;
data.length.should.equal(6); d.insert({ hello: "world" }, function (err, doc) {
var _id = doc._id;
// Everything is deserialized correctly, including deletes and indexes d.insert({ yo: "ya" }, function () {
var d = new Datastore({ filename: hookTestFilename d.update({ hello: "world" }, { $set: { hello: "earth" } }, {}, function () {
, afterSerialization: as d.remove({ yo: "ya" }, {}, function () {
, beforeDeserialization: bd d.ensureIndex({ fieldName: 'idefix' }, function () {
}) var _data = fs.readFileSync(hookTestFilename, 'utf8')
; , data = _data.split('\n')
d.loadDatabase(function () { ;
d.find({}, function (err, docs) {
docs.length.should.equal(1); data.length.should.equal(6);
docs[0].hello.should.equal("earth");
docs[0]._id.should.equal(_id); // Everything is deserialized correctly, including deletes and indexes
var d = new Datastore({ filename: hookTestFilename
Object.keys(d.indexes).length.should.equal(2); , afterSerialization: as
Object.keys(d.indexes).indexOf("idefix").should.not.equal(-1); , beforeDeserialization: bd
})
done(); ;
d.loadDatabase(function () {
d.find({}, function (err, docs) {
docs.length.should.equal(1);
docs[0].hello.should.equal("earth");
docs[0]._id.should.equal(_id);
Object.keys(d.indexes).length.should.equal(2);
Object.keys(d.indexes).indexOf("idefix").should.not.equal(-1);
done();
});
}); });
}); });
}); });
}); });
}); });
}); });
}); });
}); });

Loading…
Cancel
Save