sequelize-temporal
Advanced tools
Comparing version 1.0.5 to 1.0.6
18
index.js
@@ -6,3 +6,4 @@ var _ = require('lodash'); | ||
// for increased performance | ||
blocking: true | ||
blocking: true, | ||
full: false | ||
}; | ||
@@ -68,3 +69,3 @@ | ||
var insertHook = function(obj, options){ | ||
var dataValues = obj._previousDataValues || obj.dataValues; | ||
var dataValues = (!temporalOptions.full && obj._previousDataValues) || obj.dataValues; | ||
var historyRecord = modelHistory.create(dataValues, {transaction: options.transaction}); | ||
@@ -91,4 +92,11 @@ if(temporalOptions.blocking){ | ||
// all hooks just create a copy | ||
model.hook('beforeUpdate', insertHook); | ||
model.hook('beforeDestroy', insertHook); | ||
if (temporalOptions.full) { | ||
model.hook('afterCreate', insertHook); | ||
model.hook('afterUpdate', insertHook); | ||
model.hook('afterDestroy', insertHook); | ||
model.hook('afterRestore', insertHook); | ||
} else { | ||
model.hook('beforeUpdate', insertHook); | ||
model.hook('beforeDestroy', insertHook); | ||
} | ||
@@ -100,3 +108,3 @@ model.hook('beforeBulkUpdate', insertBulkHook); | ||
throw new Error("This is a read-only history database. You aren't allowed to modify it."); | ||
} | ||
}; | ||
@@ -103,0 +111,0 @@ modelHistory.hook('beforeUpdate', readOnlyHook); |
{ | ||
"name": "sequelize-temporal", | ||
"version": "1.0.5", | ||
"version": "1.0.6", | ||
"description": "Temporal tables for Sequelize", | ||
@@ -35,8 +35,8 @@ "main": "index.js", | ||
"devDependencies": { | ||
"chai": "^3.4.1", | ||
"chai-as-promised": "^5.1.0", | ||
"mocha": "^2.3.4", | ||
"sequelize": "^3.14.2", | ||
"sqlite3": "^3.1.1" | ||
"chai": "^4.1.2", | ||
"chai-as-promised": "^7.1.1", | ||
"mocha": "^5.2.0", | ||
"sequelize": "^4.38.0", | ||
"sqlite3": "^4.0.1" | ||
} | ||
} |
@@ -73,7 +73,14 @@ Temporal tables for Sequelize | ||
```js | ||
{ | ||
/* runs the insert within the sequelize hook chain, disable | ||
for increased performance without warranties */ | ||
blocking: true, | ||
/* By default sequelize-temporal persist only changes, and saves the previous state in the history table. | ||
The "full" option saves all transactions into the temporal database | ||
(i.e. this includes the latest state.) | ||
This allows to only query the hostory table to get the full history of an entity. | ||
*/ | ||
full: false | ||
``` | ||
// runs the insert within the sequelize hook chain, disable | ||
// for increased performance without warranties | ||
blocking: true | ||
``` | ||
@@ -80,0 +87,0 @@ Details |
123
test/test.js
@@ -19,3 +19,3 @@ var Temporal = require('../'); | ||
User = Temporal(sequelize.define('User', { | ||
name: Sequelize.TEXT | ||
name: Sequelize.TEXT | ||
}), sequelize); | ||
@@ -26,2 +26,15 @@ UserHistory = sequelize.models.UserHistory; | ||
function freshDBWithFullModeAndParanoid() { | ||
sequelize = new Sequelize('', '', '', { | ||
dialect: 'sqlite', | ||
storage: __dirname + '/.test.sqlite' | ||
}); | ||
User = Temporal(sequelize.define('User', { | ||
name: Sequelize.TEXT | ||
}, { paranoid: true }), sequelize, { full: true }); | ||
UserHistory = sequelize.models.UserHistory; | ||
return sequelize.sync({ force: true }); | ||
} | ||
function assertCount(modelHistory, n, opts){ | ||
@@ -31,3 +44,3 @@ // wrapped, chainable promise | ||
return modelHistory.count(opts).then(function(count){ | ||
assert.equal(n, count, "history entries") | ||
assert.equal(n, count, "history entries") | ||
return obj; | ||
@@ -40,2 +53,5 @@ }); | ||
beforeEach(freshDB); | ||
it('onCreate: should not store the new version in history db' , function(){ | ||
return User.create({ name: 'test' }).then(assertCount(UserHistory, 0)); | ||
}); | ||
it('onUpdate/onDestroy: should save to the historyDB' , function(){ | ||
@@ -174,3 +190,3 @@ return User.create() | ||
}); | ||
return assert.isRejected(userUpdate, Error, "Update error"); | ||
return assert.isRejected(userUpdate, Error, "Validation error"); | ||
}); | ||
@@ -181,3 +197,3 @@ it('should forbid deletes' , function(){ | ||
}); | ||
return assert.isRejected(userUpdate, Error, "Update error"); | ||
return assert.isRejected(userUpdate, Error, "Validation error"); | ||
}); | ||
@@ -192,8 +208,5 @@ }); | ||
Fruit = Temporal(sequelize.define('Fruit', { | ||
name: Sequelize.TEXT | ||
}, { | ||
instanceMethods:{ | ||
sayHi: function(){ return 2;} | ||
} | ||
name: Sequelize.TEXT | ||
}), sequelize); | ||
Fruit.prototype.sayHi = function(){ return 2;} | ||
return sequelize.sync().then(function(){ | ||
@@ -210,3 +223,3 @@ return Fruit.create(); | ||
Fruit = Temporal(sequelize.define('Fruit', { | ||
name: Sequelize.TEXT | ||
name: Sequelize.TEXT | ||
}, { | ||
@@ -242,2 +255,90 @@ hooks:{ | ||
}); | ||
}) | ||
describe('full mode', function() { | ||
beforeEach(freshDBWithFullModeAndParanoid); | ||
it('onCreate: should store the new version in history db' , function(){ | ||
return User.create({ name: 'test' }) | ||
.then(function() { | ||
return UserHistory.findAll(); | ||
}) | ||
.then(function(histories) { | ||
assert.equal(1, histories.length); | ||
assert.equal('test', histories[0].name); | ||
}); | ||
}); | ||
it('onUpdate: should store the new version to the historyDB' , function(){ | ||
return User.create({ name: 'test' }) | ||
.then(function(user) { | ||
return user.update({ name: 'renamed' }); | ||
}) | ||
.then(function() { | ||
return UserHistory.findAll(); | ||
}) | ||
.then(function(histories) { | ||
assert.equal(histories.length, 2, 'two entries in DB'); | ||
assert.equal(histories[0].name, 'test', 'first version saved'); | ||
assert.equal(histories[1].name, 'renamed', 'second version saved'); | ||
}); | ||
}); | ||
it('onDelete: should store the previous version to the historyDB' , function(){ | ||
return User.create({ name: 'test' }) | ||
.then(function(user) { | ||
return user.update({ name: 'renamed' }); | ||
}) | ||
.then(function(user) { | ||
return user.destroy(); | ||
}) | ||
.then(function() { | ||
return UserHistory.findAll(); | ||
}) | ||
.then(function(histories) { | ||
assert.equal(histories.length, 3, 'three entries in DB'); | ||
assert.equal(histories[0].name, 'test', 'first version saved'); | ||
assert.equal(histories[1].name, 'renamed', 'second version saved'); | ||
assert.notEqual(histories[2].deletedAt, null, 'deleted version saved'); | ||
}); | ||
}); | ||
it('onRestore: should store the new version to the historyDB' , function(){ | ||
return User.create({ name: 'test' }) | ||
.then(function(user) { | ||
return user.destroy(); | ||
}) | ||
.then(function(user) { | ||
return user.restore(); | ||
}) | ||
.then(function() { | ||
return UserHistory.findAll(); | ||
}) | ||
.then(function(histories) { | ||
assert.equal(histories.length, 3, 'three entries in DB'); | ||
assert.equal(histories[0].name, 'test', 'first version saved'); | ||
assert.notEqual(histories[1].deletedAt, null, 'deleted version saved'); | ||
assert.equal(histories[2].deletedAt, null, 'restored version saved'); | ||
}); | ||
}); | ||
it('should revert on failed transactions, even when using after hooks' , function(){ | ||
return sequelize.transaction() | ||
.then(function(transaction) { | ||
var options = { transaction: transaction }; | ||
return User.create({ name: 'test' }, options) | ||
.then(function(user) { | ||
return user.destroy(options); | ||
}) | ||
.then(assertCount(UserHistory, 2, options)) | ||
.then(function() { | ||
return transaction.rollback() | ||
}); | ||
}) | ||
.then(assertCount(UserHistory,0)); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
20964
402
127
0