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

Commit 0cd08d93 by Mick Hansen

Merge pull request #1286 from OtaK/master

Adding HAVING clause support to generic query generator
2 parents 0c425fb4 304c71ee
......@@ -5,6 +5,7 @@ Notice: All 1.7.x changes are present in 2.0.x aswell
- implements .spread for eventemitters [#1277](https://github.com/sequelize/sequelize/pull/1277)
- fixes some of the mysql connection error bugs [#1282](https://github.com/sequelize/sequelize/pull/1282)
- [Feature] Support for OR queries.
- [Feature] Support for HAVING queries. [#1286](https://github.com/sequelize/sequelize/pull/1286)
# v1.7.0-rc2
- fixes unixSocket connections for mariadb [#1248](https://github.com/sequelize/sequelize/pull/1248)
......
var Utils = require("../../utils")
var Utils = require("../../utils")
, SqlString = require("../../sql-string")
module.exports = (function() {
......@@ -703,6 +703,16 @@ module.exports = (function() {
mainQueryItems.push(" GROUP BY " + options.group)
}
}
// Add HAVING to sub or main query
if (options.hasOwnProperty('having')) {
options.having = this.getWhereConditions(options.having, tableName, factory, options, false)
if (subQuery) {
subQueryItems.push(" HAVING " + options.having)
} else {
mainQueryItems.push(" HAVING " + options.having)
}
}
// Add ORDER to sub or main query
if (options.order) {
......@@ -715,7 +725,6 @@ module.exports = (function() {
}
}
var limitOrder = this.addLimitAndOffset(options, query)
// Add LIMIT, OFFSET to sub or main query
......@@ -804,21 +813,26 @@ module.exports = (function() {
/*
Takes something and transforms it into values of a where condition.
*/
getWhereConditions: function(smth, tableName, factory, options) {
getWhereConditions: function(smth, tableName, factory, options, prepend) {
var result = null
, where = {}
, self = this
if (typeof prepend === 'undefined')
prepend = true
if ((smth instanceof Utils.and) || (smth instanceof Utils.or)) {
var connector = (smth instanceof Utils.and) ? ' AND ' : ' OR '
result = smth.args.map(function(arg) {
return self.getWhereConditions(arg, tableName, factory, options)
return self.getWhereConditions(arg, tableName, factory, options, prepend)
}).join(connector)
result = "(" + result + ")"
} else if (Utils.isHash(smth)) {
smth = Utils.prependTableNameToHash(tableName, smth)
if (prepend) {
smth = Utils.prependTableNameToHash(tableName, smth)
}
result = this.hashToWhereConditions(smth, factory, options)
} else if (typeof smth === 'number') {
var primaryKeys = !!factory ? Object.keys(factory.primaryKeys) : []
......@@ -846,7 +860,7 @@ module.exports = (function() {
if (treatAsAnd) {
var _smth = self.sequelize.and.apply(null, smth)
result = self.getWhereConditions(_smth, tableName, factory, options)
result = self.getWhereConditions(_smth, tableName, factory, options, prepend)
} else {
result = Utils.format(smth, this.dialect)
}
......
......@@ -236,6 +236,30 @@ if (Support.dialectIsMySQL()) {
expectation: "SELECT * FROM `myTable` GROUP BY name ORDER BY id DESC;",
context: QueryGenerator
}, {
title: 'HAVING clause works with string replacements',
arguments: ['myTable', function (sequelize) {
return {
attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']],
group: ['creationYear', 'title'],
having: ['creationYear > ?', 2002]
}
}],
expectation: "SELECT *, YEAR(`createdAt`) as `creationYear` FROM `myTable` GROUP BY `creationYear`, `title` HAVING creationYear > 2002;",
context: QueryGenerator,
needsSequelize: true
}, {
title: 'HAVING clause works with where-like hash',
arguments: ['myTable', function (sequelize) {
return {
attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']],
group: ['creationYear', 'title'],
having: { creationYear: { gt: 2002 } }
}
}],
expectation: "SELECT *, YEAR(`createdAt`) as `creationYear` FROM `myTable` GROUP BY `creationYear`, `title` HAVING `creationYear` > 2002;",
context: QueryGenerator,
needsSequelize: true
}, {
arguments: ['myTable', {limit: 10}],
expectation: "SELECT * FROM `myTable` LIMIT 10;",
context: QueryGenerator
......
......@@ -318,6 +318,30 @@ if (dialect.match(/^postgres/)) {
arguments: ['myTable', {group: ["name","title"]}],
expectation: "SELECT * FROM \"myTable\" GROUP BY \"name\", \"title\";"
}, {
title: 'HAVING clause works with string replacements',
arguments: ['myTable', function (sequelize) {
return {
attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']],
group: ['creationYear', 'title'],
having: ['creationYear > ?', 2002]
}
}],
expectation: "SELECT *, YEAR(\"createdAt\") as \"creationYear\" FROM \"myTable\" GROUP BY \"creationYear\", \"title\" HAVING creationYear > 2002;",
context: QueryGenerator,
needsSequelize: true
}, {
title: 'HAVING clause works with where-like hash',
arguments: ['myTable', function (sequelize) {
return {
attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']],
group: ['creationYear', 'title'],
having: { creationYear: { gt: 2002 } }
}
}],
expectation: "SELECT *, YEAR(\"createdAt\") as \"creationYear\" FROM \"myTable\" GROUP BY \"creationYear\", \"title\" HAVING \"creationYear\" > 2002;",
context: QueryGenerator,
needsSequelize: true
}, {
arguments: ['myTable', {limit: 10}],
expectation: "SELECT * FROM \"myTable\" LIMIT 10;"
}, {
......
......@@ -223,6 +223,30 @@ if (dialect === 'sqlite') {
expectation: "SELECT * FROM `myTable` GROUP BY name ORDER BY id DESC;",
context: QueryGenerator
}, {
title: 'HAVING clause works with string replacements',
arguments: ['myTable', function (sequelize) {
return {
attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']],
group: ['creationYear', 'title'],
having: ['creationYear > ?', 2002]
}
}],
expectation: "SELECT *, YEAR(`createdAt`) as `creationYear` FROM `myTable` GROUP BY `creationYear`, `title` HAVING creationYear > 2002;",
context: QueryGenerator,
needsSequelize: true
}, {
title: 'HAVING clause works with where-like hash',
arguments: ['myTable', function (sequelize) {
return {
attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']],
group: ['creationYear', 'title'],
having: { creationYear: { gt: 2002 } }
}
}],
expectation: "SELECT *, YEAR(`createdAt`) as `creationYear` FROM `myTable` GROUP BY `creationYear`, `title` HAVING `creationYear` > 2002;",
context: QueryGenerator,
needsSequelize: true
}, {
arguments: ['myTable', {limit: 10}],
expectation: "SELECT * FROM `myTable` LIMIT 10;",
context: QueryGenerator
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!