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

Commit 290e8954 by Martin Aspeli

Refactored and simplified create method plus outline tests

1 parent cfb657ad
...@@ -331,34 +331,28 @@ module.exports = (function() { ...@@ -331,34 +331,28 @@ module.exports = (function() {
/** /**
* Create and insert multiple instances * Create and insert multiple instances
* *
* @param {Array} values List of objects (key/value pairs) to create instances from * @param {Array} records List of objects (key/value pairs) to create instances from
* @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*
* The `success` handler is passed a list of newly inserted models.
*/
DAOFactory.prototype.bulkCreate = function(values, options) {
var factory = this
return this.bulkInsert(values.map(function(attrs) {
return factory.build(attrs, options)
}))
}
/**
* Insert multiple instances
*
* @param {Array} daos List of built DAOs
* @param {Array} fields Fields to insert (defaults to all fields) * @param {Array} fields Fields to insert (defaults to all fields)
* @return {Object} A promise which fires `success`, `error`, `complete` and `sql`. * @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
* *
* The `success` handler is passed a list of newly inserted models. * Note: the `success` handler is not passed any arguments. To obtain DAOs for
* the newly created values, you will need to query for them again. This is
* because MySQL and SQLite do not make it easy to obtain back automatically
* generated IDs and other default values in a way that can be mapped to
* multiple records
*/ */
DAOFactory.prototype.bulkInsert = function(daos, fields) { DAOFactory.prototype.bulkCreate = function(records, fields) {
var self = this var self = this
, records = [] , daos = records.map(function(v) { return self.build(v) })
, updatedAtAttr = self.options.underscored ? 'updated_at' : 'updatedAt' , updatedAtAttr = self.options.underscored ? 'updated_at' : 'updatedAt'
, createdAtAttr = self.options.underscored ? 'created_at' : 'createdAt' , createdAtAttr = self.options.underscored ? 'created_at' : 'createdAt'
// we will re-create from DAOs, which may have set up default attributes
records = []
if (fields) { if (fields) {
// Always insert updated and created time stamps
if (self.options.timestamps) { if (self.options.timestamps) {
if (fields.indexOf(updatedAtAttr) === -1) { if (fields.indexOf(updatedAtAttr) === -1) {
fields.push(updatedAtAttr) fields.push(updatedAtAttr)
...@@ -369,21 +363,25 @@ module.exports = (function() { ...@@ -369,21 +363,25 @@ module.exports = (function() {
} }
} }
// Build records for the fields we know about
daos.forEach(function(dao) { daos.forEach(function(dao) {
var values = {}; var values = {};
fields.forEach(function(field) { fields.forEach(function(field) {
if (dao.values[field] !== undefined) { values[field] = dao.values[field]
values[field] = dao.values[field]
}
}) })
if (self.options.timestamps) {
values[updatedAtAttr] = Utils.now()
}
records.push(values); records.push(values);
}) })
} else { } else {
daos.forEach(function(dao) { daos.forEach(function(dao) {
records.push(dao.values) records.push(dao.values)
}) })
} }
// Validate enums
records.forEach(function(values) { records.forEach(function(values) {
for (var attrName in self.rawAttributes) { for (var attrName in self.rawAttributes) {
if (self.rawAttributes.hasOwnProperty(attrName)) { if (self.rawAttributes.hasOwnProperty(attrName)) {
...@@ -397,11 +395,6 @@ module.exports = (function() { ...@@ -397,11 +395,6 @@ module.exports = (function() {
} }
} }
} }
if (self.options.timestamps && dao.hasOwnProperty(updatedAtAttr)) {
dao[updatedAtAttr] = values[updatedAtAttr] = Utils.now()
}
}) })
return self.QueryInterface.bulkInsert(self.tableName, records) return self.QueryInterface.bulkInsert(self.tableName, records)
......
...@@ -108,27 +108,27 @@ module.exports = (function() { ...@@ -108,27 +108,27 @@ module.exports = (function() {
} else if (this.send('isShowOrDescribeQuery')) { } else if (this.send('isShowOrDescribeQuery')) {
this.emit('success', results) this.emit('success', results)
} else if (this.send('isInsertQuery')) { } else if (this.send('isInsertQuery')) {
for (var key in rows[0]) { if(this.callee !== null) { // may happen for bulk inserts
if (rows[0].hasOwnProperty(key)) { for (var key in rows[0]) {
var record = rows[0][key] if (rows[0].hasOwnProperty(key)) {
if (!!this.callee.daoFactory.rawAttributes[key].type && !!this.callee.daoFactory.rawAttributes[key].type.type && this.callee.daoFactory.rawAttributes[key].type.type === DataTypes.HSTORE.type) { var record = rows[0][key]
record = this.callee.daoFactory.daoFactoryManager.sequelize.queryInterface.QueryGenerator.toHstore(record) if (!!this.callee.daoFactory.rawAttributes[key].type && !!this.callee.daoFactory.rawAttributes[key].type.type && this.callee.daoFactory.rawAttributes[key].type.type === DataTypes.HSTORE.type) {
} record = this.callee.daoFactory.daoFactoryManager.sequelize.queryInterface.QueryGenerator.toHstore(record)
}
this.callee[key] = record this.callee[key] = record
} }
} }
this.emit('success', this.callee) this.emit('success', this.callee)
} else if (this.send('isUpdateQuery')) { } else if (this.send('isUpdateQuery')) {
for (var key in rows[0]) { if(this.callee !== null) { // may happen for bulk updates
if (rows[0].hasOwnProperty(key)) { for (var key in rows[0]) {
var record = rows[0][key] if (rows[0].hasOwnProperty(key)) {
if (!!this.callee.daoFactory.rawAttributes[key].type && !!this.callee.daoFactory.rawAttributes[key].type.type && this.callee.daoFactory.rawAttributes[key].type.type === DataTypes.HSTORE.type) { var record = rows[0][key]
record = this.callee.daoFactory.daoFactoryManager.sequelize.queryInterface.QueryGenerator.toHstore(record) if (!!this.callee.daoFactory.rawAttributes[key].type && !!this.callee.daoFactory.rawAttributes[key].type.type && this.callee.daoFactory.rawAttributes[key].type.type === DataTypes.HSTORE.type) {
} record = this.callee.daoFactory.daoFactoryManager.sequelize.queryInterface.QueryGenerator.toHstore(record)
}
this.callee[key] = record this.callee[key] = record
} }
} }
......
...@@ -262,9 +262,7 @@ module.exports = (function() { ...@@ -262,9 +262,7 @@ module.exports = (function() {
QueryInterface.prototype.bulkInsert = function(tableName, records) { QueryInterface.prototype.bulkInsert = function(tableName, records) {
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, 'bulkInsert')
success: function(objs) { objs.forEach(function(v) { v.isNewRecord = false }) }
})
} }
QueryInterface.prototype.update = function(dao, tableName, values, identifier) { QueryInterface.prototype.update = function(dao, tableName, values, identifier) {
......
...@@ -387,6 +387,99 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -387,6 +387,99 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
describe('bulkCreate', function() {
it('inserts multiple values', function(done) {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '23'}]
this.User.bulkCreate(data, ['username']).success(function(users) {
// self.User.find(user.id).success(function(_user) {
// expect(_user.username).toEqual(data.username)
// expect(_user.secretValue).not.toEqual(data.secretValue)
// expect(_user.secretValue).toEqual(null)
done()
})
})
}) // - bulkCreate
// it('should only store the values passed in the witelist', function(done) {
// var self = this
// , data = { username: 'Peter', secretValue: '42' }
// this.User.create(data, ['username']).success(function(user) {
// self.User.find(user.id).success(function(_user) {
// expect(_user.username).toEqual(data.username)
// expect(_user.secretValue).not.toEqual(data.secretValue)
// expect(_user.secretValue).toEqual(null)
// done()
// })
// })
// })
// it('should store all values if no whitelist is specified', function(done) {
// var self = this
// , data = { username: 'Peter', secretValue: '42' }
// this.User.create(data).success(function(user) {
// self.User.find(user.id).success(function(_user) {
// expect(_user.username).toEqual(data.username)
// expect(_user.secretValue).toEqual(data.secretValue)
// done()
// })
// })
// })
// it('saves data with single quote', function(done) {
// var quote = "single'quote"
// , self = this
// this.User.create({ data: quote }).success(function(user) {
// expect(user.data).toEqual(quote, 'memory single quote')
// self.User.find({where: { id: user.id }}).success(function(user) {
// expect(user.data).toEqual(quote, 'SQL single quote')
// done()
// })
// })
// })
// it('saves data with double quote', function(done) {
// var quote = 'double"quote'
// , self = this
// this.User.create({ data: quote }).success(function(user) {
// expect(user.data).toEqual(quote, 'memory double quote')
// self.User.find({where: { id: user.id }}).success(function(user) {
// expect(user.data).toEqual(quote, 'SQL double quote')
// done()
// })
// })
// })
// it('saves stringified JSON data', function(done) {
// var json = JSON.stringify({ key: 'value' })
// , self = this
// this.User.create({ data: json }).success(function(user) {
// expect(user.data).toEqual(json, 'memory data')
// self.User.find({where: { id: user.id }}).success(function(user) {
// expect(user.data).toEqual(json, 'SQL data')
// done()
// })
// })
// })
// it('stores the current date in createdAt', function(done) {
// this.User.create({ username: 'foo' }).success(function(user) {
// expect(parseInt(+user.createdAt/5000)).toEqual(parseInt(+new Date()/5000))
// done()
// })
// })
describe('find', function find() { describe('find', function find() {
before(function(done) { before(function(done) {
this.User.create({ this.User.create({
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!