不要怂,就是干,撸起袖子干!

Commit d0bec74b by Michael Storgaard

Added dirty tracking

1 parent 9a41b4ae
...@@ -377,7 +377,7 @@ module.exports = (function() { ...@@ -377,7 +377,7 @@ module.exports = (function() {
} }
DAOFactory.prototype.build = function(values, options) { DAOFactory.prototype.build = function(values, options) {
options = options || { isNewRecord: true } options = options || { isNewRecord: true, isDirty: true }
var self = this var self = this
, instance = new this.DAO(values, this.options, options.isNewRecord) , instance = new this.DAO(values, this.options, options.isNewRecord)
...@@ -385,6 +385,7 @@ module.exports = (function() { ...@@ -385,6 +385,7 @@ module.exports = (function() {
instance.isNewRecord = options.isNewRecord instance.isNewRecord = options.isNewRecord
instance.daoFactoryName = this.name instance.daoFactoryName = this.name
instance.daoFactory = this instance.daoFactory = this
instance.isDirty = options.isDirty
return instance return instance
} }
......
...@@ -84,10 +84,15 @@ module.exports = (function() { ...@@ -84,10 +84,15 @@ module.exports = (function() {
DAO.prototype.getDataValue = function(name) { DAO.prototype.getDataValue = function(name) {
return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name] return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
} }
DAO.prototype.get = DAO.prototype.getDataValue
DAO.prototype.setDataValue = function(name, value) { DAO.prototype.setDataValue = function(name, value) {
if (this.dataValues[name] != value) {
this.isDirty = true
}
this.dataValues[name] = value this.dataValues[name] = value
} }
DAO.prototype.set = DAO.prototype.setDataValue
// if an array with field names is passed to save() // if an array with field names is passed to save()
// only those fields will be updated // only those fields will be updated
...@@ -149,6 +154,7 @@ module.exports = (function() { ...@@ -149,6 +154,7 @@ module.exports = (function() {
}).run() }).run()
} }
else if (this.isNewRecord) { else if (this.isNewRecord) {
this.isDirty = false
return this.QueryInterface.insert(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory), values) return this.QueryInterface.insert(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory), values)
} else { } else {
var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id }; var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id };
...@@ -157,6 +163,7 @@ module.exports = (function() { ...@@ -157,6 +163,7 @@ module.exports = (function() {
identifier = this.__options.whereCollection; identifier = this.__options.whereCollection;
} }
this.isDirty = false
var tableName = this.QueryInterface.QueryGenerator.addSchema(this.__factory) var tableName = this.QueryInterface.QueryGenerator.addSchema(this.__factory)
, query = this.QueryInterface.update(this, tableName, values, identifier) , query = this.QueryInterface.update(this, tableName, values, identifier)
...@@ -191,6 +198,7 @@ module.exports = (function() { ...@@ -191,6 +198,7 @@ module.exports = (function() {
this[valueName] = obj.values[valueName] this[valueName] = obj.values[valueName]
} }
} }
this.isDirty = false
emitter.emit('success', this) emitter.emit('success', this)
}.bind(this)) }.bind(this))
}.bind(this)).run() }.bind(this)).run()
...@@ -224,14 +232,21 @@ module.exports = (function() { ...@@ -224,14 +232,21 @@ module.exports = (function() {
readOnlyAttributes.push('updatedAt') readOnlyAttributes.push('updatedAt')
readOnlyAttributes.push('deletedAt') readOnlyAttributes.push('deletedAt')
var isDirty = this.isDirty
Utils._.each(updates, function(value, attr) { Utils._.each(updates, function(value, attr) {
var updateAllowed = ( var updateAllowed = (
(readOnlyAttributes.indexOf(attr) == -1) && (readOnlyAttributes.indexOf(attr) == -1) &&
(readOnlyAttributes.indexOf(Utils._.underscored(attr)) == -1) && (readOnlyAttributes.indexOf(Utils._.underscored(attr)) == -1) &&
(self.attributes.indexOf(attr) > -1) (self.attributes.indexOf(attr) > -1)
) )
updateAllowed && (self[attr] = value) if (updateAllowed) {
if (self[attr] != value) {
isDirty = true
}
self[attr] = value
}
}) })
this.isDirty = isDirty
} }
DAO.prototype.destroy = function() { DAO.prototype.destroy = function() {
...@@ -330,7 +345,15 @@ module.exports = (function() { ...@@ -330,7 +345,15 @@ module.exports = (function() {
// (the same is true for __defineSetter and 'prototype' getters) // (the same is true for __defineSetter and 'prototype' getters)
if (has !== true) { if (has !== true) {
this.__defineGetter__(attribute, has.get || function() { return this.dataValues[attribute]; }); this.__defineGetter__(attribute, has.get || function() { return this.dataValues[attribute]; });
this.__defineSetter__(attribute, has.set || function(v) { this.dataValues[attribute] = v; }); this.__defineSetter__(attribute, has.set || function(v) {
if (this.dataValues[attribute] != v) {
//Only dirty the object if the change is not due to id, touchedAt, createdAt or updatedAt being initiated
if (this.dataValues[attribute] || (attribute != 'id' && attribute != 'touchedAt' && attribute != 'createdAt' && attribute != 'updatedAt')) {
this.isDirty = true
}
}
this.dataValues[attribute] = v;
});
} }
this[attribute] = value; this[attribute] = value;
......
...@@ -262,7 +262,7 @@ module.exports = (function() { ...@@ -262,7 +262,7 @@ module.exports = (function() {
result = transformRowsWithEagerLoadingIntoDaos.call(this, results) result = transformRowsWithEagerLoadingIntoDaos.call(this, results)
} else { } else {
result = results.map(function(result) { result = results.map(function(result) {
return this.callee.build(result, { isNewRecord: false }) return this.callee.build(result, { isNewRecord: false, isDirty: false })
}.bind(this)) }.bind(this))
} }
......
...@@ -110,6 +110,116 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -110,6 +110,116 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
}) })
}) })
describe('isDirty', function() {
it('returns true for non-saved objects', function(done) {
var user = this.User.build({ username: 'user' })
expect(user.id).to.be.null
expect(user.isDirty).to.be.ok
done()
})
it("returns false for saved objects", function(done) {
this.User.build({ username: 'user' }).save().success(function(user) {
expect(user.isDirty).to.not.be.ok
done()
})
})
it("returns true for changed attribute", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.username = 'new'
expect(user.isDirty).to.be.ok
done()
})
})
it("returns false for non-changed attribute", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.username = 'user'
expect(user.isDirty).to.not.be.ok
done()
})
})
it("returns true for bulk changed attribute", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.setAttributes({
username: 'new',
aNumber: 1
})
expect(user.isDirty).to.be.ok
done()
})
})
it("returns false for bulk non-changed attribute", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.setAttributes({
username: 'user'
})
expect(user.isDirty).to.not.be.ok
done()
})
})
it("returns true for changed and bulk non-changed attribute", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.aNumber = 1
user.setAttributes({
username: 'user'
})
expect(user.isDirty).to.be.ok
done()
})
})
it("returns true for changed attribute and false for saved object", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.username = 'new'
expect(user.isDirty).to.be.ok
user.save().success(function() {
expect(user.isDirty).to.not.be.ok
done()
})
})
})
it("returns false for created objects", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
expect(user.isDirty).to.not.be.ok
done()
})
})
it("returns false for objects found by find method", function(done) {
var self = this
this.User.create({ username: 'user' }).success(function(user) {
self.User.find(user.id).success(function(user) {
expect(user.isDirty).to.not.be.ok
done()
})
})
})
it("returns false for objects found by findAll method", function(done) {
var self = this
, users = []
for (var i = 0; i < 10; i++) {
users[users.length] = {username: 'user'}
}
this.User.bulkCreate(users).success(function() {
self.User.findAll().success(function(users) {
users.forEach(function(u) {
expect(u.isDirty).to.not.be.ok
})
done()
})
})
})
})
describe('increment', function () { describe('increment', function () {
beforeEach(function(done) { beforeEach(function(done) {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).complete(function(){ this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).complete(function(){
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!