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

Commit 3b951e13 by Martin Aspeli

Rename and rationalise methods as per discussion on GitHub

1 parent 31ec3a19
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
- [BUG] Null dates don't break SQLite anymore. [#572](https://github.com/sequelize/sequelize/pull/572). thanks to mweibel - [BUG] Null dates don't break SQLite anymore. [#572](https://github.com/sequelize/sequelize/pull/572). thanks to mweibel
- [FEATURE] Schematics. [#564](https://github.com/sequelize/sequelize/pull/564). thanks to durango - [FEATURE] Schematics. [#564](https://github.com/sequelize/sequelize/pull/564). thanks to durango
- [FEATURE] Foreign key constraints. [#595](https://github.com/sequelize/sequelize/pull/595). thanks to optilude - [FEATURE] Foreign key constraints. [#595](https://github.com/sequelize/sequelize/pull/595). thanks to optilude
- [FEATURE] Support for bulk insert (`<DAOFactory>.bulkCreate()`, update (`<DAOFactory>`.bulkUpdate()`) and delete (`<DAOFactory>`.bulkDelete()`) - [FEATURE] Support for bulk insert (`<DAOFactory>.bulkCreate()`, update (`<DAOFactory>`.update()`) and delete (`<DAOFactory>`.destroy()`)
# v1.6.0 # # v1.6.0 #
- [DEPENDENCIES] upgrade mysql to alpha7. You *MUST* use this version or newer for DATETIMEs to work - [DEPENDENCIES] upgrade mysql to alpha7. You *MUST* use this version or newer for DATETIMEs to work
......
...@@ -406,7 +406,7 @@ module.exports = (function() { ...@@ -406,7 +406,7 @@ module.exports = (function() {
* @param {Object} where 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`. * @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*/ */
DAOFactory.prototype.bulkDelete = function(where) { DAOFactory.prototype.destroy = function(where) {
if (this.options.timestamps && this.options.paranoid) { if (this.options.timestamps && this.options.paranoid) {
var attr = this.options.underscored ? 'deleted_at' : 'deletedAt' var attr = this.options.underscored ? 'deleted_at' : 'deletedAt'
var attrValueHash = {} var attrValueHash = {}
...@@ -424,7 +424,7 @@ module.exports = (function() { ...@@ -424,7 +424,7 @@ module.exports = (function() {
* @param {Object} where 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`. * @return {Object} A promise which fires `success`, `error`, `complete` and `sql`.
*/ */
DAOFactory.prototype.bulkUpdate = function(attrValueHash, where) { DAOFactory.prototype.update = function(attrValueHash, where) {
if(this.options.timestamps) { if(this.options.timestamps) {
var attr = this.options.underscored ? 'updated_at' : 'updatedAt' var attr = this.options.underscored ? 'updated_at' : 'updatedAt'
attrValueHash[attr] = Utils.now() attrValueHash[attr] = Utils.now()
......
...@@ -285,13 +285,20 @@ module.exports = (function() { ...@@ -285,13 +285,20 @@ module.exports = (function() {
deleteQuery: function(tableName, where, options) { deleteQuery: function(tableName, where, options) {
options = options || {} options = options || {}
options.limit = options.limit || 1
var table = QueryGenerator.addQuotes(tableName) var table = QueryGenerator.addQuotes(tableName)
var where = QueryGenerator.getWhereConditions(where) var where = QueryGenerator.getWhereConditions(where)
var limit = Utils.escape(options.limit) var limit = ""
var query = "DELETE FROM " + table + " WHERE " + where + " LIMIT " + limit if(Utils._.isUndefined(options.limit)) {
options.limit = 1;
}
if(!!options.limit) {
limit = " LIMIT " + Utils.escape(options.limit)
}
var query = "DELETE FROM " + table + " WHERE " + where + limit
return query return query
}, },
......
...@@ -301,18 +301,7 @@ module.exports = (function() { ...@@ -301,18 +301,7 @@ module.exports = (function() {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull) attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)
var query = "INSERT INTO <%= table %> (<%= attributes %>) VALUES (<%= values %>) RETURNING *;" var query = "INSERT INTO <%= table %> (<%= attributes %>) VALUES (<%= values %>) RETURNING *;"
, returning = [] , returning = removeSerialsFromHash(tableName, attrValueHash)
Utils._.forEach(attrValueHash, function(value, key, hash) {
if (tables[tableName] && tables[tableName][key]) {
switch (tables[tableName][key]) {
case 'serial':
delete hash[key]
returning.push(key)
break
}
}
});
var replacements = { var replacements = {
table: QueryGenerator.addQuotes(tableName) table: QueryGenerator.addQuotes(tableName)
...@@ -332,18 +321,7 @@ module.exports = (function() { ...@@ -332,18 +321,7 @@ module.exports = (function() {
, tuples = [] , tuples = []
Utils._.forEach(attrValueHashes, function(attrValueHash) { Utils._.forEach(attrValueHashes, function(attrValueHash) {
removeSerialsFromHash(tableName, attrValueHash)
// don't insert serials (Postgres doesn't like it when they're NULL)
Utils._.forEach(attrValueHash, function(value, key, hash) {
if (tables[tableName] && tables[tableName][key]) {
switch (tables[tableName][key]) {
case 'serial':
delete hash[key]
break
}
}
});
tuples.push("(" + tuples.push("(" +
Utils._.values(attrValueHash).map(function(value){ Utils._.values(attrValueHash).map(function(value){
return QueryGenerator.pgEscape(value) return QueryGenerator.pgEscape(value)
...@@ -384,38 +362,14 @@ module.exports = (function() { ...@@ -384,38 +362,14 @@ module.exports = (function() {
deleteQuery: function(tableName, where, options) { deleteQuery: function(tableName, where, options) {
options = options || {} options = options || {}
options.limit = options.limit || 1
primaryKeys[tableName] = primaryKeys[tableName] || []; if(Utils._.isUndefined(options.limit)) {
options.limit = 1;
var query = "DELETE FROM <%= table %> WHERE <%= primaryKeys %> IN (SELECT <%= primaryKeysSelection %> FROM <%= table %> WHERE <%= where %> LIMIT <%= limit %>)"
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),
limit: QueryGenerator.pgEscape(options.limit),
primaryKeys: primaryKeys[tableName].length > 1 ? '(' + pks + ')' : pks,
primaryKeysSelection: pks
} }
return Utils._.template(query)(replacements)
},
bulkDeleteQuery: function(tableName, where, options) {
options = options || {}
primaryKeys[tableName] = primaryKeys[tableName] || []; primaryKeys[tableName] = primaryKeys[tableName] || [];
var query = "DELETE FROM <%= table %> WHERE <%= primaryKeys %> IN (SELECT <%= primaryKeysSelection %> FROM <%= table %> WHERE <%= where %>)" var query = "DELETE FROM <%= table %> WHERE <%= primaryKeys %> IN (SELECT <%= primaryKeysSelection %> FROM <%= table %> WHERE <%= where %><%= limit %>)"
var pks; var pks;
if (primaryKeys[tableName] && primaryKeys[tableName].length > 0) { if (primaryKeys[tableName] && primaryKeys[tableName].length > 0) {
...@@ -429,6 +383,7 @@ module.exports = (function() { ...@@ -429,6 +383,7 @@ module.exports = (function() {
var replacements = { var replacements = {
table: QueryGenerator.addQuotes(tableName), table: QueryGenerator.addQuotes(tableName),
where: QueryGenerator.getWhereConditions(where), where: QueryGenerator.getWhereConditions(where),
limit: !!options.limit? " LIMIT " + QueryGenerator.pgEscape(options.limit) : "",
primaryKeys: primaryKeys[tableName].length > 1 ? '(' + pks + ')' : pks, primaryKeys: primaryKeys[tableName].length > 1 ? '(' + pks + ')' : pks,
primaryKeysSelection: pks primaryKeysSelection: pks
} }
...@@ -782,5 +737,22 @@ module.exports = (function() { ...@@ -782,5 +737,22 @@ module.exports = (function() {
} }
} }
// Private
var removeSerialsFromHash = function(tableName, attrValueHash) {
var returning = [];
Utils._.forEach(attrValueHash, function(value, key, hash) {
if (tables[tableName] && tables[tableName][key]) {
switch (tables[tableName][key]) {
case 'serial':
delete hash[key]
returning.push(key)
break
}
}
});
return returning;
}
return Utils._.extend(Utils._.clone(require("../query-generator")), QueryGenerator) return Utils._.extend(Utils._.clone(require("../query-generator")), QueryGenerator)
})() })()
...@@ -172,20 +172,7 @@ module.exports = (function() { ...@@ -172,20 +172,7 @@ module.exports = (function() {
var query = "DELETE FROM <%= table %> WHERE <%= where %>" var query = "DELETE FROM <%= table %> WHERE <%= where %>"
var replacements = { var replacements = {
table: Utils.addTicks(tableName), table: Utils.addTicks(tableName),
where: this.getWhereConditions(where), where: MySqlQueryGenerator.getWhereConditions(where)
limit: Utils.escape(options.limit)
}
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) return Utils._.template(query)(replacements)
......
...@@ -281,7 +281,7 @@ module.exports = (function() { ...@@ -281,7 +281,7 @@ module.exports = (function() {
} }
QueryInterface.prototype.bulkDelete = function(tableName, identifier) { QueryInterface.prototype.bulkDelete = function(tableName, identifier) {
var sql = this.QueryGenerator.bulkDeleteQuery(tableName, identifier) var sql = this.QueryGenerator.deleteQuery(tableName, identifier, {limit: null})
return queryAndEmit.call(this, sql, 'bulkDelete') return queryAndEmit.call(this, sql, 'bulkDelete')
} }
......
...@@ -271,19 +271,9 @@ describe('QueryGenerator', function() { ...@@ -271,19 +271,9 @@ describe('QueryGenerator', function() {
}, { }, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {limit: 10}], arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {limit: 10}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo\\';DROP TABLE myTable;' LIMIT 10" expectation: "DELETE FROM `myTable` WHERE `name`='foo\\';DROP TABLE myTable;' LIMIT 10"
}
],
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;"}], arguments: ['myTable', {name: 'foo'}, {limit: null}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo\\';DROP TABLE myTable;'" expectation: "DELETE FROM `myTable` WHERE `name`='foo'"
} }
], ],
......
...@@ -304,25 +304,9 @@ describe('QueryGenerator', function() { ...@@ -304,25 +304,9 @@ describe('QueryGenerator', function() {
}, { }, {
arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}, {limit: 10}], arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}, {limit: 10}],
expectation: "DELETE FROM \"mySchema\".\"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"mySchema\".\"myTable\" WHERE \"name\"='foo'';DROP TABLE mySchema.myTable;' LIMIT 10)" expectation: "DELETE FROM \"mySchema\".\"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"mySchema\".\"myTable\" WHERE \"name\"='foo'';DROP TABLE mySchema.myTable;' LIMIT 10)"
}
],
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'}], arguments: ['myTable', {name: 'foo'}, {limit: null}],
expectation: "DELETE FROM \"mySchema\".\"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"mySchema\".\"myTable\" WHERE \"name\"='foo')" expectation: "DELETE FROM \"myTable\" WHERE \"id\" IN (SELECT \"id\" FROM \"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;')"
} }
], ],
......
...@@ -189,6 +189,25 @@ describe('QueryGenerator', function() { ...@@ -189,6 +189,25 @@ describe('QueryGenerator', function() {
expectation: "UPDATE `myTable` SET `bar`=2 WHERE `name`='foo'", expectation: "UPDATE `myTable` SET `bar`=2 WHERE `name`='foo'",
context: {options: {omitNull: true}} context: {options: {omitNull: true}}
} }
],
deleteQuery: [
{
arguments: ['myTable', {name: 'foo'}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo'"
}, {
arguments: ['myTable', 1],
expectation: "DELETE FROM `myTable` WHERE `id`=1"
}, {
arguments: ['myTable', 1, {limit: 10}],
expectation: "DELETE FROM `myTable` WHERE `id`=1"
}, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {limit: 10}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo\\';DROP TABLE myTable;'"
}, {
arguments: ['myTable', {name: 'foo'}, {limit: null}],
expectation: "DELETE FROM `myTable` WHERE `name`='foo'"
}
] ]
}; };
......
...@@ -536,7 +536,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -536,7 +536,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) // - bulkCreate }) // - bulkCreate
describe('bulkUpdate', function() { describe('update', function() {
it('updates only values that match filter', function(done) { it('updates only values that match filter', function(done) {
var self = this var self = this
...@@ -546,7 +546,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -546,7 +546,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.bulkUpdate({username: 'Bill'}, {secretValue: '42'}) self.User.update({username: 'Bill'}, {secretValue: '42'})
.success(function() { .success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(3) expect(users.length).toEqual(3)
...@@ -569,7 +569,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -569,7 +569,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.bulkUpdate({username: 'Bill'}, {secretValue: '42'}) self.User.update({username: 'Bill'}, {secretValue: '42'})
.success(function() { .success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(3) expect(users.length).toEqual(3)
...@@ -588,9 +588,9 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -588,9 +588,9 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
}) // - bulkUpdate }) // - update
describe('bulkDelete', function() { describe('destroy', function() {
it('deletes values that match filter', function(done) { it('deletes values that match filter', function(done) {
var self = this var self = this
...@@ -600,7 +600,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -600,7 +600,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.bulkDelete({secretValue: '42'}) self.User.destroy({secretValue: '42'})
.success(function() { .success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(1) expect(users.length).toEqual(1)
...@@ -631,7 +631,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -631,7 +631,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
User.bulkCreate(data).success(function() { User.bulkCreate(data).success(function() {
User.bulkDelete({secretValue: '42'}) User.destroy({secretValue: '42'})
.success(function() { .success(function() {
User.findAll({order: 'id'}).success(function(users) { User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(3) expect(users.length).toEqual(3)
...@@ -653,7 +653,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -653,7 +653,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) // - bulkDelete }) // - destroy
describe('find', function find() { describe('find', function find() {
before(function(done) { before(function(done) {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!