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

Commit e9dc214a by Sascha Depold

transaction support for bulkCreate/bulkInsert/save

1 parent a3a53654
...@@ -636,32 +636,39 @@ module.exports = (function() { ...@@ -636,32 +636,39 @@ module.exports = (function() {
* generated IDs and other default values in a way that can be mapped to * generated IDs and other default values in a way that can be mapped to
* multiple records * multiple records
*/ */
DAOFactory.prototype.bulkCreate = function(records, fields, options) { DAOFactory.prototype.bulkCreate = function(records, fieldsOrOptions, options) {
options = options || {} Utils.validateParameter(fieldsOrOptions, Object, { deprecated: Array, optional: true })
options.validate = options.validate === undefined ? false : Boolean(options.validate) Utils.validateParameter(options, 'undefined', { deprecated: Object, optional: true })
options.hooks = options.hooks === undefined ? false : Boolean(options.hooks)
fields = fields || [] options = Utils._.extend({
validate: false,
hooks: false
}, options || {})
if (fieldsOrOptions instanceof Array) {
options.fields = fieldsOrOptions
} else {
options.fields = options.fields || []
options = Utils._.extend(options, fieldsOrOptions)
}
var self = this var self = this
, updatedAtAttr = Utils._.underscoredIf(self.options.updatedAt, self.options.underscored) , updatedAtAttr = Utils._.underscoredIf(self.options.updatedAt, self.options.underscored)
, createdAtAttr = Utils._.underscoredIf(self.options.createdAt, self.options.underscored) , createdAtAttr = Utils._.underscoredIf(self.options.createdAt, self.options.underscored)
, errors = [] , errors = []
, daos = records.map(function(v) { , daos = records.map(function(v) { return self.build(v) })
return self.build(v)
})
return new Utils.CustomEventEmitter(function(emitter) { return new Utils.CustomEventEmitter(function(emitter) {
var done = function() { var done = function() {
self.runHooks('afterBulkCreate', daos, fields, function(err, newRecords, newFields) { self.runHooks('afterBulkCreate', daos, options.fields, function(err, newRecords, newFields) {
if (!!err) { if (!!err) {
return emitter.emit('error', err) return emitter.emit('error', err)
} }
daos = newRecords || daos daos = newRecords || daos
fields = newFields || fields options.fields = newFields || options.fields
emitter.emit('success', daos, fields) emitter.emit('success', daos, options.fields)
}) })
} }
...@@ -678,7 +685,8 @@ module.exports = (function() { ...@@ -678,7 +685,8 @@ module.exports = (function() {
} }
daos[i] = newValues || daos[i] daos[i] = newValues || daos[i]
daos[i].save().error(function(err) { console.log('....................')
daos[i].save({ transaction: options.transaction }).error(function(err) {
emitter.emit('error', err) emitter.emit('error', err)
}).success(function() { }).success(function() {
self.runHooks('afterCreate', daos[i], function(err, newValues) { self.runHooks('afterCreate', daos[i], function(err, newValues) {
...@@ -706,9 +714,9 @@ module.exports = (function() { ...@@ -706,9 +714,9 @@ module.exports = (function() {
records = [] records = []
daos.forEach(function(dao) { daos.forEach(function(dao) {
var values = fields.length > 0 ? {} : dao.dataValues var values = options.fields.length > 0 ? {} : dao.dataValues
fields.forEach(function(field) { options.fields.forEach(function(field) {
values[field] = dao.dataValues[field] values[field] = dao.dataValues[field]
}) })
...@@ -725,7 +733,7 @@ module.exports = (function() { ...@@ -725,7 +733,7 @@ module.exports = (function() {
records.push(values) records.push(values)
}) })
self.QueryInterface.bulkInsert(self.tableName, records) self.QueryInterface.bulkInsert(self.tableName, records, options)
.on('sql', function(sql) { .on('sql', function(sql) {
emitter.emit('sql', sql) emitter.emit('sql', sql)
}) })
...@@ -736,18 +744,18 @@ module.exports = (function() { ...@@ -736,18 +744,18 @@ module.exports = (function() {
}) })
} }
self.runHooks('beforeBulkCreate', daos, fields, function(err, newRecords, newFields) { self.runHooks('beforeBulkCreate', daos, options.fields, function(err, newRecords, newFields) {
if (!!err) { if (!!err) {
return emitter.emit('error', err) return emitter.emit('error', err)
} }
daos = newRecords || daos daos = newRecords || daos
fields = newFields || fields options.fields = newFields || options.fields
if (options.validate === true) { if (options.validate === true) {
if (options.hooks === true) { if (options.hooks === true) {
var iterate = function(i) { var iterate = function(i) {
daos[i].hookValidate({skip: fields}).error(function(err) { daos[i].hookValidate({skip: options.fields}).error(function(err) {
errors[errors.length] = {record: v, errors: err} errors[errors.length] = {record: v, errors: err}
i++ i++
if (i > daos.length) { if (i > daos.length) {
...@@ -762,7 +770,7 @@ module.exports = (function() { ...@@ -762,7 +770,7 @@ module.exports = (function() {
} }
} else { } else {
daos.forEach(function(v) { daos.forEach(function(v) {
var valid = v.validate({skip: fields}) var valid = v.validate({skip: options.fields})
if (valid !== null) { if (valid !== null) {
errors[errors.length] = {record: v, errors: valid} errors[errors.length] = {record: v, errors: valid}
} }
......
...@@ -451,9 +451,9 @@ module.exports = (function() { ...@@ -451,9 +451,9 @@ module.exports = (function() {
}) })
} }
QueryInterface.prototype.bulkInsert = function(tableName, records) { QueryInterface.prototype.bulkInsert = function(tableName, records, options) {
var sql = this.QueryGenerator.bulkInsertQuery(tableName, records) var sql = this.QueryGenerator.bulkInsertQuery(tableName, records)
return queryAndEmit.call(this, sql, 'bulkInsert') return queryAndEmit.call(this, [sql, null, options], 'bulkInsert')
} }
QueryInterface.prototype.update = function(dao, tableName, values, identifier, options) { QueryInterface.prototype.update = function(dao, tableName, values, identifier, options) {
......
...@@ -7,7 +7,7 @@ var ParameterValidator = module.exports = { ...@@ -7,7 +7,7 @@ var ParameterValidator = module.exports = {
optional: false optional: false
}, options || {}) }, options || {})
if (options.optional && (value === undefined)) { if (options.optional && ((value === undefined) || (value === null)) ) {
return true return true
} }
...@@ -50,6 +50,9 @@ var validate = function(value, expectation, options) { ...@@ -50,6 +50,9 @@ var validate = function(value, expectation, options) {
} else if (!options.throwError) { } else if (!options.throwError) {
return false return false
} else { } else {
throw new Error('The parameter (value: ' + value.toString() + ') is no ' + expectation + '.') var _value = (value === null) ? 'null' : value.toString()
, _expectation = expectation.toString().match(/function ([^\(]+)/)[1]
throw new Error('The parameter (value: ' + _value + ') is no ' + _expectation + '.')
} }
} }
...@@ -1028,6 +1028,28 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -1028,6 +1028,28 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
describe('bulkCreate', function() { describe('bulkCreate', function() {
it("supports transactions", function(done) {
Support.prepareTransactionTest(dialect, this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction(function(t) {
User
.bulkCreate([{ username: 'foo' }, { username: 'bar' }], { transaction: t })
.success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(2)
t.rollback().success(done)
})
})
})
})
})
})
})
it('properly handles disparate field lists', function(done) { it('properly handles disparate field lists', function(done) {
var self = this var self = this
, data = [{username: 'Peter', secretValue: '42' }, , data = [{username: 'Peter', secretValue: '42' },
......
...@@ -564,6 +564,26 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -564,6 +564,26 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
}) })
describe('save', function() { describe('save', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(dialect, this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction(function(t) {
User.build({ username: 'foo' }).save({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(1)
t.rollback().success(done)
})
})
})
})
})
})
})
it('only updates fields in passed array', function(done) { it('only updates fields in passed array', function(done) {
var self = this var self = this
, userId = null , userId = null
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!