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

Commit 5a75d260 by Jan Aagaard Meier

Refactored model.update and destroy to use promises

1 parent 1bd525d2
Showing with 109 additions and 189 deletions
......@@ -92,7 +92,9 @@ Hooks.runHooks = function() {
if (!!arguments[0]) {
return reject(arguments[0])
}
resolveArgs = Array.prototype.slice.call(arguments, 1)
if (arguments.length) {
resolveArgs = Array.prototype.slice.call(arguments, 1)
}
return run(hooks[tick])
}))
......@@ -101,7 +103,9 @@ Hooks.runHooks = function() {
maybePromise.spread(function () {
tick++
resolveArgs = Array.prototype.slice.call(arguments)
if (arguments.length) {
resolveArgs = Array.prototype.slice.call(arguments)
}
return run(hooks[tick])
}, reject)
......
......@@ -636,7 +636,7 @@ module.exports = (function() {
* @param {Object} [options] A hash of options to describe the scope of the search
* @param {Object} [options.where] A hash of attributes to describe your search. See above for examples.
* @param {Array<String>} [options.attributes] A list of the attributes that you want to select
* @param {Array<Object|Model>} [options.include] A list of associations to eagerly load. Supported is either { include: [ Model1, Model2, ...] } or { include: [ { model: Model1, as: 'Alias' } ] }. If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z }`, you need to specify Z in the as attribute when eager loading Y). When using the object form, you can also specify `attributes` to specify what columns to load, `where` to limit the relations, and `include` to load further nested relations
* @param {Array<Object|Model>} [options.include] A list of associations to eagerly load. Supported is either { include: [ Model1, Model2, ...] } or { include: [ { model: Model1, as: 'Alias' } ] }. If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z }`, you need to specify Z in the as attribute when eager loading Y). When using the object form, you can also specify `attributes` to specify what columns to load, `where` to limit the relations, and `include` to load further nested relations
* @param {String|Array|Sequelize.fn} [options.order] Specifies an ordering. If a string is provided, it will be esacped. Using an array, you can provide several columns / functions to order by. Each element can be further wrapped in a two-element array. The first element is the column / function to order by, the second is the direction. For example: `order: [['name', 'DESC']]`. In this way the column will be escaped, but the direction will not.
* @param {Number} [options.limit]
* @param {Number} [options.offset]
......@@ -1266,106 +1266,65 @@ module.exports = (function() {
, query = null
, args = []
return new Utils.CustomEventEmitter(function(emitter) {
self.runHooks(self.options.hooks.beforeBulkDestroy, where, function(err, newWhere) {
if (!!err) {
return emitter.emit('error', err)
}
where = newWhere || where
return self.runHooks(self.options.hooks.beforeBulkDestroy, where).then(function(newWhere) {
where = newWhere || where
if (self._timestampAttributes.deletedAt && options.force === false) {
var attrValueHash = {}
attrValueHash[self._timestampAttributes.deletedAt] = Utils.now()
query = 'bulkUpdate'
args = [self.getTableName(), attrValueHash, where, self]
} else {
query = 'bulkDelete'
args = [self.getTableName(), where, options, self]
}
var runQuery = function(err, records) {
if (!!err) {
return emitter.emit('error', err)
}
if (self._timestampAttributes.deletedAt && options.force === false) {
var attrValueHash = {}
attrValueHash[self._timestampAttributes.deletedAt] = Utils.now()
query = 'bulkUpdate'
args = [self.getTableName(), attrValueHash, where, self]
} else {
query = 'bulkDelete'
args = [self.getTableName(), where, options, self]
}
query = self.QueryInterface[query].apply(self.QueryInterface, args)
query.on('sql', function(sql) {
emitter.emit('sql', sql)
})
.error(function(err) {
emitter.emit('error', err)
})
.success(function(results) {
var finished = function(err) {
if (!!err) {
return emitter.emit('error', err)
}
var runQuery = function(records) {
return self.QueryInterface[query].apply(self.QueryInterface, args).then(function(results) {
if (options && options.hooks === true) {
var tick = 0
var next = function(i) {
return self.runHooks(self.options.hooks.afterDestroy, records[i]).then(function(newValues) {
records[i].dataValues = !!newValues ? newValues.dataValues : records[i].dataValues
tick++
self.runHooks(self.options.hooks.afterBulkDestroy, where, function(err) {
if (!!err) {
return emitter.emit('error', err)
if (tick >= records.length) {
return self.runHooks(self.options.hooks.afterBulkDestroy, where).return(results)
}
emitter.emit('success', results)
return next(tick)
})
}
if (options && options.hooks === true) {
var tick = 0
var next = function(i) {
self.runHooks(self.options.hooks.afterDestroy, records[i], function(err, newValues) {
if (!!err) {
return finished(err)
}
records[i].dataValues = !!newValues ? newValues.dataValues : records[i].dataValues
tick++
return next(tick)
} else {
return self.runHooks(self.options.hooks.afterBulkDestroy, where).return(results)
}
})
}
if (tick >= records.length) {
return finished()
}
if (options && options.hooks === true) {
var tick = 0
return self.all({where: where}).then(function(records) {
var next = function(i) {
return self.runHooks(self.options.hooks.beforeDestroy, records[i]).then(function(newValues) {
records[i].dataValues = !!newValues ? newValues.dataValues : records[i].dataValues
tick++
next(tick)
})
if (tick >= records.length) {
return runQuery(records)
}
next(tick)
} else {
finished()
}
})
}
if (options && options.hooks === true) {
var tick = 0
self.all({where: where}).error(function(err) { emitter.emit('error', err) })
.success(function(records) {
var next = function(i) {
self.runHooks(self.options.hooks.beforeDestroy, records[i], function(err, newValues) {
if (!!err) {
return runQuery(err)
}
records[i].dataValues = !!newValues ? newValues.dataValues : records[i].dataValues
tick++
if (tick >= records.length) {
return runQuery(null, records)
}
next(tick)
})
}
return next(tick)
})
}
next(tick)
})
//
} else {
runQuery()
}
})
}).run()
return next(tick)
})
} else {
return runQuery()
}
})
}
/**
......@@ -1383,7 +1342,6 @@ module.exports = (function() {
*/
Model.prototype.update = function(attrValueHash, where, options) {
var self = this
, query = null
, tick = 0
options = options || {}
......@@ -1395,121 +1353,79 @@ module.exports = (function() {
attrValueHash[self._timestampAttributes.updatedAt] = Utils.now()
}
return new Utils.CustomEventEmitter(function(emitter) {
var runSave = function() {
self.runHooks(self.options.hooks.beforeBulkUpdate, attrValueHash, where, function(err, attributes, _where) {
if (!!err) {
return emitter.emit('error', err)
}
where = _where || where
attrValueHash = attributes || attrValueHash
var runQuery = function(err, records) {
if (!!err) {
return emitter.emit('error', err)
}
var runSave = function() {
return self.runHooks(self.options.hooks.beforeBulkUpdate, attrValueHash, where).spread(function(attributes, _where) {
where = _where || where
attrValueHash = attributes || attrValueHash
query = self.QueryInterface.bulkUpdate(self.getTableName(), attrValueHash, where, options, self.rawAttributes)
query.on('sql', function(sql) {
emitter.emit('sql', sql)
})
.error(function(err) {
emitter.emit('error', err)
})
.success(function(results) {
var finished = function(err, records) {
if (!!err) {
return emitter.emit('error', err)
}
var runQuery = function(records) {
return self.QueryInterface.bulkUpdate(self.getTableName(), attrValueHash, where, options, self.rawAttributes).then(function(results) {
if (options && options.hooks === true && !!records && records.length > 0) {
var tick = 0
var next = function(i) {
return self.runHooks(self.options.hooks.afterUpdate, records[i]).then(function(newValues) {
records[i].dataValues = (!!newValues && newValues.dataValues) ? newValues.dataValues : records[i].dataValues
tick++
self.runHooks(self.options.hooks.afterBulkUpdate, attrValueHash, where, function(err) {
if (!!err) {
return emitter.emit('error', err)
if (tick >= records.length) {
return self.runHooks(self.options.hooks.afterBulkUpdate, attrValueHash, where).return(records)
}
emitter.emit('success', records)
return next(tick)
})
}
if (options && options.hooks === true && !!records && records.length > 0) {
var tick = 0
var next = function(i) {
self.runHooks(self.options.hooks.afterUpdate, records[i], function(err, newValues) {
if (!!err) {
return finished(err)
}
return next(tick)
} else {
return self.runHooks(self.options.hooks.afterBulkUpdate, attrValueHash, where).return(results)
}
})
}
records[i].dataValues = !!newValues ? newValues.dataValues : records[i].dataValues
tick++
if (options.hooks === true) {
return self.all({where: where}).then(function(records) {
if (records === null || records.length < 1) {
return runQuery()
}
if (tick >= records.length) {
return finished(null, records)
}
var next = function(i) {
return self.runHooks(self.options.hooks.beforeUpdate, records[i]).then(function(newValues) {
records[i].dataValues = (!!newValues && newValues.dataValues) ? newValues.dataValues : records[i].dataValues
tick++
next(tick)
})
if (tick >= records.length) {
return runQuery(records)
}
next(tick)
} else {
finished(null, results)
}
})
}
if (options.hooks === true) {
self.all({where: where}).error(function(err) { emitter.emit('error', err) })
.success(function(records) {
if (records === null || records.length < 1) {
return runQuery(null)
}
var next = function(i) {
self.runHooks(self.options.hooks.beforeUpdate, records[i], function(err, newValues) {
if (!!err) {
return runQuery(err)
}
records[i].dataValues = !!newValues ? newValues.dataValues : records[i].dataValues
tick++
if (tick >= records.length) {
return runQuery(null, records)
}
next(tick)
})
}
return next(tick)
})
}
next(tick)
})
} else {
runQuery()
}
})
}
return next(tick)
})
} else {
return runQuery()
}
})
}
if (options.validate === true) {
var build = self.build(attrValueHash)
if (options.validate === true) {
var build = self.build(attrValueHash)
// We want to skip validations for all other fields
var updatedFields = Object.keys(attrValueHash)
var skippedFields = Utils._.difference(Object.keys(self.attributes), updatedFields)
// We want to skip validations for all other fields
var updatedFields = Object.keys(attrValueHash)
var skippedFields = Utils._.difference(Object.keys(self.attributes), updatedFields)
build.hookValidate({skip: skippedFields}).error(function(err) {
emitter.emit('error', err)
}).success(function(attributes) {
if (!!attributes && !!attributes.dataValues) {
attrValueHash = Utils._.pick.apply(Utils._, [].concat(attributes.dataValues).concat(Object.keys(attrValueHash)))
}
return build.hookValidate({skip: skippedFields}).then(function(attributes) {
if (!!attributes && !!attributes.dataValues) {
attrValueHash = Utils._.pick.apply(Utils._, [].concat(attributes.dataValues).concat(Object.keys(attrValueHash)))
}
runSave()
})
} else {
runSave()
}
}).run()
return runSave()
})
} else {
return runSave()
}
}
/**
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!