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

Commit 8b937dd7 by Sushant

change(bulkCreate): only support non-empty array as updateOnDuplicate

1 parent 66fb6b67
...@@ -2323,7 +2323,7 @@ class Model { ...@@ -2323,7 +2323,7 @@ class Model {
* *
* @return {Promise<Array<Model>>} * @return {Promise<Array<Model>>}
*/ */
static bulkCreate(records, options) { static bulkCreate(records, options = {}) {
if (!records.length) { if (!records.length) {
return Promise.resolve([]); return Promise.resolve([]);
} }
...@@ -2333,25 +2333,28 @@ class Model { ...@@ -2333,25 +2333,28 @@ class Model {
hooks: true, hooks: true,
individualHooks: false, individualHooks: false,
ignoreDuplicates: false ignoreDuplicates: false
}, options || {}); }, options);
options.fields = options.fields || Object.keys(this.tableAttributes); options.fields = options.fields || Object.keys(this.tableAttributes);
const dialect = this.sequelize.options.dialect; const dialect = this.sequelize.options.dialect;
if (options.ignoreDuplicates && ['postgres', 'mssql'].indexOf(dialect) !== -1) {
return Promise.reject(new Error(dialect + ' does not support the \'ignoreDuplicates\' option.')); if (options.ignoreDuplicates && ['postgres', 'mssql'].includes(dialect)) {
return Promise.reject(new Error(`${dialect} does not support the ignoreDuplicates option.`));
} }
if (options.updateOnDuplicate && dialect !== 'mysql') { if (options.updateOnDuplicate && dialect !== 'mysql') {
return Promise.reject(new Error(dialect + ' does not support the \'updateOnDuplicate\' option.')); return Promise.reject(new Error(`${dialect} does not support the updateOnDuplicate option.`));
} }
if (options.updateOnDuplicate) { if (options.updateOnDuplicate !== undefined) {
// By default, all attributes except 'createdAt' can be updated if (_.isArray(options.updateOnDuplicate) && options.updateOnDuplicate.length) {
let updatableAttributes = _.pull(Object.keys(this.tableAttributes), 'createdAt'); options.updateOnDuplicate = _.intersection(
if (_.isArray(options.updateOnDuplicate) && !_.isEmpty(options.updateOnDuplicate)) { _.without(Object.keys(this.tableAttributes), this._timestampAttributes.createdAt),
updatableAttributes = _.intersection(updatableAttributes, options.updateOnDuplicate); options.updateOnDuplicate
);
} else {
return Promise.reject(new Error('updateOnDuplicate option only supports non-empty array.'));
} }
options.updateOnDuplicate = updatableAttributes;
} }
options.model = this; options.model = this;
......
...@@ -442,31 +442,54 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -442,31 +442,54 @@ describe(Support.getTestDialectTeaser('Model'), () => {
} }
if (current.dialect.supports.updateOnDuplicate) { if (current.dialect.supports.updateOnDuplicate) {
it('should support the updateOnDuplicate option', function() { describe('updateOnDuplicate', () => {
const self = this; it('should support the updateOnDuplicate option', function() {
const data = [ const data = [
{ uniqueName: 'Peter', secretValue: '42' }, { uniqueName: 'Peter', secretValue: '42' },
{ uniqueName: 'Paul', secretValue: '23' } { uniqueName: 'Paul', secretValue: '23' }
];
return this.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'], updateOnDuplicate: ['secretValue'] }).then(() => {
const new_data = [
{ uniqueName: 'Peter', secretValue: '43' },
{ uniqueName: 'Paul', secretValue: '24' },
{ uniqueName: 'Michael', secretValue: '26' }
]; ];
return self.User.bulkCreate(new_data, { fields: ['uniqueName', 'secretValue'], updateOnDuplicate: ['secretValue'] }).then(() => {
return self.User.findAll({order: ['id']}).then(users => { return this.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'], updateOnDuplicate: ['secretValue'] }).then(() => {
expect(users.length).to.equal(3); const new_data = [
expect(users[0].uniqueName).to.equal('Peter'); { uniqueName: 'Peter', secretValue: '43' },
expect(users[0].secretValue).to.equal('43'); { uniqueName: 'Paul', secretValue: '24' },
expect(users[1].uniqueName).to.equal('Paul'); { uniqueName: 'Michael', secretValue: '26' }
expect(users[1].secretValue).to.equal('24'); ];
expect(users[2].uniqueName).to.equal('Michael'); return this.User.bulkCreate(new_data, { fields: ['uniqueName', 'secretValue'], updateOnDuplicate: ['secretValue'] }).then(() => {
expect(users[2].secretValue).to.equal('26'); return this.User.findAll({order: ['id']}).then(users => {
expect(users.length).to.equal(3);
expect(users[0].uniqueName).to.equal('Peter');
expect(users[0].secretValue).to.equal('43');
expect(users[1].uniqueName).to.equal('Paul');
expect(users[1].secretValue).to.equal('24');
expect(users[2].uniqueName).to.equal('Michael');
expect(users[2].secretValue).to.equal('26');
});
}); });
}); });
}); });
it('should reject for non array updateOnDuplicate option', function() {
const data = [
{ uniqueName: 'Peter', secretValue: '42' },
{ uniqueName: 'Paul', secretValue: '23' }
];
return expect(
this.User.bulkCreate(data, { updateOnDuplicate: true })
).to.be.rejectedWith('updateOnDuplicate option only supports non-empty array.');
});
it('should reject for empty array updateOnDuplicate option', function() {
const data = [
{ uniqueName: 'Peter', secretValue: '42' },
{ uniqueName: 'Paul', secretValue: '23' }
];
return expect(
this.User.bulkCreate(data, { updateOnDuplicate: [] })
).to.be.rejectedWith('updateOnDuplicate option only supports non-empty array.');
});
}); });
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!