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

Commit ade36f1e by Martin Aspeli

Test + fix for bulk delete

1 parent a8a12542
......@@ -403,17 +403,17 @@ module.exports = (function() {
/**
* Delete multiple instances
*
* @param {Object} options Options to describe the scope of the search.
* @param {Object} where Options to describe the scope of the search.
* @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*/
DAOFactory.prototype.bulkDelete = function(options) {
DAOFactory.prototype.bulkDelete = function(where) {
if (this.options.timestamps && this.options.paranoid) {
var attr = this.options.underscored ? 'deleted_at' : 'deletedAt'
var attrValueHash = {}
attrValueHash[attr] = Utils.now()
return this.QueryInterface.bulkUpdate(this.tableName, attrValueHash, options)
return this.QueryInterface.bulkUpdate(this.tableName, attrValueHash, where)
} else {
return this.QueryInterface.bulkDelete(this.tableName, options)
return this.QueryInterface.bulkDelete(this.tableName, where)
}
}
......@@ -421,15 +421,15 @@ module.exports = (function() {
* Update multiple instances
*
* @param {Object} attrValueHash A hash of fields to change and their new values
* @param {Object} options Options to describe the scope of the search.
* @param {Object} where Options to describe the scope of the search.
* @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*/
DAOFactory.prototype.bulkUpdate = function(attrValueHash, options) {
DAOFactory.prototype.bulkUpdate = function(attrValueHash, where) {
if(this.options.timestamps) {
var attr = this.options.underscored ? 'updated_at' : 'updatedAt'
attrValueHash[attr] = Utils.now()
}
return this.QueryInterface.bulkUpdate(this.tableName, attrValueHash, options)
return this.QueryInterface.bulkUpdate(this.tableName, attrValueHash, where)
}
// private
......
......@@ -296,6 +296,18 @@ module.exports = (function() {
return query
},
bulkDeleteQuery: function(tableName, where, options) {
options = options || {}
var query = "DELETE FROM <%= table %> WHERE <%= where %>"
var replacements = {
table: QueryGenerator.addQuotes(tableName),
where: QueryGenerator.getWhereConditions(where)
}
return Utils._.template(query)(replacements)
},
incrementQuery: function (tableName, attrValueHash, where) {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)
......
......@@ -410,6 +410,32 @@ module.exports = (function() {
return Utils._.template(query)(replacements)
},
bulkDeleteQuery: function(tableName, where, options) {
options = options || {}
primaryKeys[tableName] = primaryKeys[tableName] || [];
var query = "DELETE FROM <%= table %> WHERE <%= primaryKeys %> IN (SELECT <%= primaryKeysSelection %> FROM <%= table %> WHERE <%= where %>)"
var pks;
if (primaryKeys[tableName] && primaryKeys[tableName].length > 0) {
pks = primaryKeys[tableName].map(function(pk) {
return QueryGenerator.addQuotes(pk)
}).join(',')
} else {
pks = QueryGenerator.addQuotes('id')
}
var replacements = {
table: QueryGenerator.addQuotes(tableName),
where: QueryGenerator.getWhereConditions(where),
primaryKeys: primaryKeys[tableName].length > 1 ? '(' + pks + ')' : pks,
primaryKeysSelection: pks
}
return Utils._.template(query)(replacements)
},
incrementQuery: function(tableName, attrValueHash, where) {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)
......
......@@ -156,6 +156,19 @@ module.exports = (function() {
},
/*
Returns a bulk deletion query.
Parameters:
- tableName -> Name of the table
- where -> A hash with conditions (e.g. {name: 'foo'})
OR an ID as integer
OR a string with conditions (e.g. 'name="foo"').
If you use a string, you have to escape it on your own.
*/
deleteQuery: function(tableName, where, options) {
throwMethodUndefined('bulkDeleteQuery')
},
/*
Returns an update query.
Parameters:
- tableName -> Name of the table
......
......@@ -179,6 +179,18 @@ module.exports = (function() {
return Utils._.template(query)(replacements)
},
bulkDeleteQuery: function(tableName, where, options) {
options = options || {}
var query = "DELETE FROM <%= table %> WHERE <%= where %>"
var replacements = {
table: Utils.addTicks(tableName),
where: this.getWhereConditions(where)
}
return Utils._.template(query)(replacements)
},
incrementQuery: function(tableName, attrValueHash, where) {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)
......
......@@ -281,7 +281,7 @@ module.exports = (function() {
}
QueryInterface.prototype.bulkDelete = function(tableName, identifier) {
var sql = this.QueryGenerator.deleteQuery(tableName, identifier)
var sql = this.QueryGenerator.bulkDeleteQuery(tableName, identifier)
return queryAndEmit.call(this, sql, 'bulkDelete')
}
......
......@@ -274,6 +274,19 @@ describe('QueryGenerator', function() {
}
],
bulkDeleteQuery: [
{
arguments: ['myTable', {name: 'foo'}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo'"
}, {
arguments: ['myTable', 1],
expectation: "DELETE FROM `myTable` WHERE `id`=1"
}, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo\\';DROP TABLE myTable;'"
}
],
addIndexQuery: [
{
arguments: ['User', ['username', 'isAdmin']],
......
......@@ -307,6 +307,25 @@ describe('QueryGenerator', function() {
}
],
bulkDeleteQuery: [
{
arguments: ['myTable', {name: 'foo'}],
expectation: "DELETE FROM \"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"myTable\" WHERE \"name\"='foo')"
}, {
arguments: ['myTable', 1],
expectation: "DELETE FROM \"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"myTable\" WHERE \"id\"=1)"
}, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}],
expectation: "DELETE FROM \"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"myTable\" WHERE \"name\"='foo'';DROP TABLE myTable;')"
}, {
arguments: ['mySchema.myTable', {name: 'foo'}],
expectation: "DELETE FROM \"mySchema\".\"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"mySchema\".\"myTable\" WHERE \"name\"='foo')"
}, {
arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}],
expectation: "DELETE FROM \"mySchema\".\"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"mySchema\".\"myTable\" WHERE \"name\"='foo'';DROP TABLE mySchema.myTable;')"
}
],
addIndexQuery: [
{
arguments: ['User', ['username', 'isAdmin']],
......
......@@ -590,6 +590,71 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) // - bulkUpdate
describe('bulkDelete', function() {
it('deletes values that match filter', function(done) {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }]
this.User.bulkCreate(data).success(function() {
self.User.bulkDelete({secretValue: '42'})
.success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(1)
expect(users[0].username).toEqual("Bob")
done()
})
})
})
})
it('sets deletedAt to the current timestamp if paranoid is true', function(done) {
var self = this
, User = this.sequelize.define('ParanoidUser', {
username: Sequelize.STRING,
secretValue: Sequelize.STRING,
data: Sequelize.STRING
}, {
paranoid: true
})
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }]
User.sync({ force: true }).success(function() {
User.bulkCreate(data).success(function() {
User.bulkDelete({secretValue: '42'})
.success(function() {
User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(3)
expect(users[0].username).toEqual("Peter")
expect(users[1].username).toEqual("Paul")
expect(users[2].username).toEqual("Bob")
expect(parseInt(+users[0].deletedAt/5000)).toEqual(parseInt(+new Date()/5000))
expect(parseInt(+users[1].deletedAt/5000)).toEqual(parseInt(+new Date()/5000))
expect(parseInt(+users[2].deletedAt)).not.toEqual(parseInt(+new Date()/5000))
done()
})
})
})
})
})
}) // - bulkDelete
describe('find', function find() {
before(function(done) {
this.User.create({
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!