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

Commit 6ef1f5eb by Daniel Durante

Allows us to define our own timestamp columns.

This commit allows the user to predefine their own timestamp columns which is
useful for databases that already exist. This also allows the user to have their
own naming conventions for the timestamp columns.

The following options have been added when defining a new table:

* createdAt (defaults to "createdAt")
* updatedAt (defaults to "updatedAt")
* deletedAt (defaults to "deletedAt")
* touchedAt (defaults to "touchedAt")

Note: The underscored option still remains useful since it's just a simple one
line option which allows flexibility for those rare cases in which people decide
to change the structure of their database from camelCase to under_score or
vice-versa.
1 parent d633069a
...@@ -9,6 +9,10 @@ module.exports = (function() { ...@@ -9,6 +9,10 @@ module.exports = (function() {
var DAOFactory = function(name, attributes, options) { var DAOFactory = function(name, attributes, options) {
this.options = Utils._.extend({ this.options = Utils._.extend({
timestamps: true, timestamps: true,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
deletedAt: 'deletedAt',
touchedAt: 'touchedAt',
instanceMethods: {}, instanceMethods: {},
classMethods: {}, classMethods: {},
validate: {}, validate: {},
...@@ -560,8 +564,8 @@ module.exports = (function() { ...@@ -560,8 +564,8 @@ module.exports = (function() {
fields = fields || [] fields = fields || []
var self = this var self = this
, updatedAtAttr = self.options.underscored ? 'updated_at' : 'updatedAt' , updatedAtAttr = Utils._.underscoredIf(self.options.updatedAt, self.options.underscored)
, createdAtAttr = self.options.underscored ? 'created_at' : 'createdAt' , createdAtAttr = Utils._.underscoredIf(self.options.createdAt, self.options.underscored)
, errors = [] , errors = []
, daos = records.map(function(v) { , daos = records.map(function(v) {
var build = self.build(v) var build = self.build(v)
...@@ -629,7 +633,7 @@ module.exports = (function() { ...@@ -629,7 +633,7 @@ module.exports = (function() {
*/ */
DAOFactory.prototype.destroy = function(where, options) { DAOFactory.prototype.destroy = function(where, options) {
if (this.options.timestamps && this.options.paranoid) { if (this.options.timestamps && this.options.paranoid) {
var attr = this.options.underscored ? 'deleted_at' : 'deletedAt' var attr = Utils._.underscoredIf(this.options.deletedAt, this.options.underscored)
var attrValueHash = {} var attrValueHash = {}
attrValueHash[attr] = Utils.now() attrValueHash[attr] = Utils.now()
return this.QueryInterface.bulkUpdate(this.tableName, attrValueHash, where) return this.QueryInterface.bulkUpdate(this.tableName, attrValueHash, where)
...@@ -650,7 +654,7 @@ module.exports = (function() { ...@@ -650,7 +654,7 @@ module.exports = (function() {
options.validate = options.validate || true options.validate = options.validate || true
if(this.options.timestamps) { if(this.options.timestamps) {
var attr = this.options.underscored ? 'updated_at' : 'updatedAt' var attr = Utils._.underscoredIf(this.options.updatedAt, this.options.underscored)
attrValueHash[attr] = Utils.now() attrValueHash[attr] = Utils.now()
} }
...@@ -708,11 +712,11 @@ module.exports = (function() { ...@@ -708,11 +712,11 @@ module.exports = (function() {
} }
if (this.options.timestamps) { if (this.options.timestamps) {
defaultAttributes[Utils._.underscoredIf('createdAt', this.options.underscored)] = {type: DataTypes.DATE, allowNull: false} defaultAttributes[Utils._.underscoredIf(this.options.createdAt, this.options.underscored)] = {type: DataTypes.DATE, allowNull: false}
defaultAttributes[Utils._.underscoredIf('updatedAt', this.options.underscored)] = {type: DataTypes.DATE, allowNull: false} defaultAttributes[Utils._.underscoredIf(this.options.updatedAt, this.options.underscored)] = {type: DataTypes.DATE, allowNull: false}
if (this.options.paranoid) if (this.options.paranoid)
defaultAttributes[Utils._.underscoredIf('deletedAt', this.options.underscored)] = {type: DataTypes.DATE} defaultAttributes[Utils._.underscoredIf(this.options.deletedAt, this.options.underscored)] = {type: DataTypes.DATE}
} }
Utils._.each(defaultAttributes, function(value, attr) { Utils._.each(defaultAttributes, function(value, attr) {
......
...@@ -28,7 +28,7 @@ module.exports = (function() { ...@@ -28,7 +28,7 @@ module.exports = (function() {
Object.defineProperty(DAO.prototype, 'isDeleted', { Object.defineProperty(DAO.prototype, 'isDeleted', {
get: function() { get: function() {
var result = this.__options.timestamps && this.__options.paranoid var result = this.__options.timestamps && this.__options.paranoid
result = result && this.dataValues[this.__options.underscored ? 'deleted_at' : 'deletedAt'] !== null result = result && this.dataValues[Utils._.underscoredIf(this.__options.deletedAt, this.__options.underscored)] !== null
return result return result
} }
...@@ -99,8 +99,8 @@ module.exports = (function() { ...@@ -99,8 +99,8 @@ module.exports = (function() {
DAO.prototype.save = function(fields, options) { DAO.prototype.save = function(fields, options) {
var self = this var self = this
, values = fields ? {} : this.dataValues , values = fields ? {} : this.dataValues
, updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt' , updatedAtAttr = Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored)
, createdAtAttr = this.__options.underscored ? 'created_at' : 'createdAt' , createdAtAttr = Utils._.underscoredIf(this.__options.createdAt, this.__options.underscored)
if (fields) { if (fields) {
if (self.__options.timestamps) { if (self.__options.timestamps) {
...@@ -244,17 +244,17 @@ module.exports = (function() { ...@@ -244,17 +244,17 @@ module.exports = (function() {
readOnlyAttributes.push('id') readOnlyAttributes.push('id')
if (this.isNewRecord !== true) { if (this.isNewRecord !== true) {
readOnlyAttributes.push(this.daoFactory.options.underscored === true ? 'created_at' : 'createdAt') readOnlyAttributes.push(Utils._.underscoredIf(this.daoFactory.options.createdAt, this.daoFactory.options.underscored))
} }
// readOnlyAttributes.push(this.daoFactory.options.underscored === true ? 'updated_at' : 'updatedAt') // readOnlyAttributes.push(this.daoFactory.options.underscored === true ? 'updated_at' : 'updatedAt')
readOnlyAttributes.push(this.daoFactory.options.underscored === true ? 'deleted_at' : 'deletedAt') readOnlyAttributes.push(this.daoFactory.options.deletedAt, this.daoFactory.options.underscored)
var isDirty = this.isDirty 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)
) )
...@@ -270,7 +270,7 @@ module.exports = (function() { ...@@ -270,7 +270,7 @@ module.exports = (function() {
// since we're updating the record, we should be updating the updatedAt column.. // since we're updating the record, we should be updating the updatedAt column..
if (this.daoFactory.options.timestamps === true) { if (this.daoFactory.options.timestamps === true) {
isDirty = true isDirty = true
self[this.daoFactory.options.underscored === true ? 'updated_at' : 'updatedAt'] = new Date() self[Utils._.underscoredIf(this.daoFactory.options.updatedAt, this.daoFactory.options.underscored)] = new Date()
} }
this.isDirty = isDirty this.isDirty = isDirty
...@@ -278,7 +278,7 @@ module.exports = (function() { ...@@ -278,7 +278,7 @@ module.exports = (function() {
DAO.prototype.destroy = function() { DAO.prototype.destroy = function() {
if (this.__options.timestamps && this.__options.paranoid) { if (this.__options.timestamps && this.__options.paranoid) {
var attr = this.__options.underscored ? 'deleted_at' : 'deletedAt' var attr = Utils._.underscoredIf(this.__options.deletedAt, this.__options.underscored)
this.dataValues[attr] = new Date() this.dataValues[attr] = new Date()
return this.save() return this.save()
} else { } else {
...@@ -371,9 +371,9 @@ module.exports = (function() { ...@@ -371,9 +371,9 @@ module.exports = (function() {
this.__defineSetter__(attribute, has.set || function(v) { this.__defineSetter__(attribute, has.set || function(v) {
if (Utils.hasChanged(this.dataValues[attribute], v)) { if (Utils.hasChanged(this.dataValues[attribute], v)) {
//Only dirty the object if the change is not due to id, touchedAt, createdAt or updatedAt being initiated //Only dirty the object if the change is not due to id, touchedAt, createdAt or updatedAt being initiated
var updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt' var updatedAtAttr = Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored)
, createdAtAttr = this.__options.underscored ? 'created_at' : 'createdAt' , createdAtAttr = Utils._.underscoredIf(this.__options.createdAt, this.__options.underscored)
, touchedAtAttr = this.__options.underscored ? 'touched_at' : 'touchedAt' , touchedAtAttr = Utils._.underscoredIf(this.__options.touchedAt, this.__options.underscored)
if (this.dataValues[attribute] || (attribute != 'id' && attribute != touchedAtAttr && attribute != createdAtAttr && attribute != updatedAtAttr)) { if (this.dataValues[attribute] || (attribute != 'id' && attribute != touchedAtAttr && attribute != createdAtAttr && attribute != updatedAtAttr)) {
this.isDirty = true this.isDirty = true
...@@ -419,11 +419,11 @@ module.exports = (function() { ...@@ -419,11 +419,11 @@ module.exports = (function() {
} }
if (this.__options.timestamps) { if (this.__options.timestamps) {
defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now(this.sequelize.options.dialect) defaults[Utils._.underscoredIf(this.__options.createdAt, this.__options.underscored)] = Utils.now(this.sequelize.options.dialect)
defaults[this.__options.underscored ? 'updated_at' : 'updatedAt'] = Utils.now(this.sequelize.options.dialect) defaults[Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored)] = Utils.now(this.sequelize.options.dialect)
if (this.__options.paranoid) { if (this.__options.paranoid) {
defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null defaults[Utils._.underscoredIf(this.__options.deletedAt, this.__options.underscored)] = null
} }
} }
} }
......
...@@ -107,6 +107,53 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -107,6 +107,53 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}).to.throw(Error, 'A model validator function must not have the same name as a field. Model: Foo, field/validation name: field') }).to.throw(Error, 'A model validator function must not have the same name as a field. Model: Foo, field/validation name: field')
done() done()
}) })
it('should allow me to override updatedAt, createdAt, and deletedAt fields', function(done) {
var UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER
}, {
timestamps: true,
updatedAt: 'updatedOn',
createdAt: 'dateCreated',
deletedAt: 'deletedAtThisTime',
paranoid: true
})
UserTable.sync({force: true}).success(function() {
UserTable.create({aNumber: 4}).success(function(user) {
expect(user.updatedOn).to.exist
expect(user.dateCreated).to.exist
user.destroy().success(function(user) {
expect(user.deletedAtThisTime).to.exist
done()
})
})
})
})
it('should allow me to override updatedAt, createdAt, and deletedAt fields with underscored being true', function(done) {
var UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER
}, {
timestamps: true,
updatedAt: 'updatedOn',
createdAt: 'dateCreated',
deletedAt: 'deletedAtThisTime',
paranoid: true,
underscored: true
})
UserTable.sync({force: true}).success(function() {
UserTable.create({aNumber: 4}).success(function(user) {
expect(user.updated_on).to.exist
expect(user.date_created).to.exist
user.destroy().success(function(user) {
expect(user.deleted_at_this_time).to.exist
done()
})
})
})
})
}) })
describe('build', function() { describe('build', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!