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

Commit efe24074 by Sascha Depold

Merge branch 'refresh' of git://github.com/innofluence/sequelize into innofluence-refresh

2 parents 6a21270f 22817a09
......@@ -20,3 +20,4 @@ language: node_js
node_js:
- 0.8
# v2.0.0 #
- [DEPENDENCIES] upgrade mysql to alpha7. You *MUST* use this version or newer for DATETIMEs to work
# v1.6.0 #
- [DEPENDENCIES] upgrade mysql to alpha7. You *MUST* use this version or newer for DATETIMEs to work
- [DEPENDENCIES] upgraded most dependencies. most important: mysql was upgraded to 2.0.0-alpha-3
- [DEPENDENCIES] mysql is now an optional dependency. #355 (thanks to clkao)
- [REFACTORING] separated tests for dialects
......@@ -42,6 +40,7 @@
- [FEATURE] add increment and decrement methods on dao. #408 (thanks to janmeier/innofluence)
- [FEATURE] unified the result of describeTable
- [FEATURE] add support for decimals (thanks to alexyoung)
- [FEATURE] added DAO.reload(), which updates the attributes of the DAO in-place (as opposed to doing having to do a find() and returning a new model)
# v1.5.0 #
- [REFACTORING] use underscore functions for Utils.isHash (thanks to Mick-Hansen/innofluence)
......
......@@ -151,6 +151,17 @@ module.exports = (function() {
}
}
/*
* Refresh the current instance in-place, i.e. update the object with current data from the DB and return the same object.
* This is different from doing a `find(DAO.id)`, because that would create and return a new object. With this method,
* all references to the DAO are updated with the new data and no new objects are created.
*
* @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*/
DAO.prototype.reload = function() {
return this.QueryInterface.reload(this, this.__factory.tableName);
}
/*
* Validate this dao's attribute values according to validation rules set in the dao definition.
*
......
......@@ -225,6 +225,36 @@ module.exports = (function() {
return queryAndEmit.call(this, [sql, dao], 'increment');
}
QueryInterface.prototype.reload = function(dao, tableName) {
var self = this
return new Utils.CustomEventEmitter(function(emitter) {
var sql = self.QueryGenerator.selectQuery(tableName, { where: { id : dao.id }, limit: 1 })
, calleeStub = {
build: function (values) {
// We cannot use setAttributes here, since a refresh might also update the read only attributes
Utils._.each(values, function(value, attr) {
(dao.attributes.indexOf(attr) > -1) && (dao[attr] = value)
})
}
}
, qry = self.sequelize.query(sql, calleeStub, { plain: true, raw: false, type: 'SELECT' })
qry
.success(function () {
self.emit('refresh', null)
emitter.emit('success', dao)
})
.error(function(err) {
self.emit('refresh', err)
emitter.emit('error', err)
})
.on('sql', function(sql) {
emitter.emit('sql', sql)
})
}).run()
}
QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelector) {
var self = this
......
......@@ -216,6 +216,63 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
});
});
describe('refresh', function () {
it("should return a reference to the same DAO instead of creating a new one", function (done) {
this.User.create({ username: 'John Doe' }).done(function (err, originalUser) {
originalUser.updateAttributes({ username: 'Doe John' }).done(function () {
originalUser.reload().done(function (err, updatedUser) {
expect(originalUser === updatedUser).toBeTrue()
done();
})
})
})
})
it("should update the values on all references to the DAO", function (done) {
var self = this
this.User.create({ username: 'John Doe' }).done(function (err, originalUser) {
self.User.find(originalUser.id).done(function (err, updater) {
updater.updateAttributes({ username: 'Doe John' }).done(function () {
// We used a different reference when calling updateAttributes, so originalUser is now out of sync
expect(originalUser.username).toEqual('John Doe')
originalUser.reload().done(function (err, updatedUser) {
expect(originalUser.username).toEqual('Doe John')
expect(updatedUser.username).toEqual('Doe John')
done();
})
})
})
})
})
it("should update read only attributes as well (updatedAt)", function (done) {
var self = this
this.timeout = 2000;
this.User.create({ username: 'John Doe' }).done(function (err, originalUser) {
var originallyUpdatedAt = originalUser.updatedAt
// Wait for a second, so updatedAt will actually be different
setTimeout(function () {
self.User.find(originalUser.id).done(function (err, updater) {
updater.updateAttributes({ username: 'Doe John' }).done(function () {
originalUser.reload().done(function (err, updatedUser) {
expect(originalUser.updatedAt).toBeGreaterThan(originallyUpdatedAt)
expect(updatedUser.updatedAt).toBeGreaterThan(originallyUpdatedAt)
done();
})
})
})
}, 1000)
})
})
});
describe('default values', function() {
describe('current date', function() {
it('should store a date in touchedAt', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!