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

Commit bad4f0b3 by Mick Hansen

Merge pull request #1361 from sequelize/include-and-or-tests

Include: support .and()/.or() - Fixes #1341 & #1291
2 parents 4b12ea9d 44e7dbdc
...@@ -5,6 +5,7 @@ Notice: All 1.7.x changes are present in 2.0.x aswell ...@@ -5,6 +5,7 @@ Notice: All 1.7.x changes are present in 2.0.x aswell
- [BUG] sync() no longer fails with foreign key constraints references own table (toposort self-dependency error) - [BUG] sync() no longer fails with foreign key constraints references own table (toposort self-dependency error)
- [FEATURE] makes it possible to specify exactly what timestamp attributes you want to utilize [#1334](https://github.com/sequelize/sequelize/pull/1334) - [FEATURE] makes it possible to specify exactly what timestamp attributes you want to utilize [#1334](https://github.com/sequelize/sequelize/pull/1334)
- [FEATURE] Support coffee script files in migrations. [#1357](https://github.com/sequelize/sequelize/pull/1357) - [FEATURE] Support coffee script files in migrations. [#1357](https://github.com/sequelize/sequelize/pull/1357)
- [FEATURE] include.where now supports Sequelize.and()/.or(). [#1361](https://github.com/sequelize/sequelize/pull/1361)
# v1.7.0-rc4 # v1.7.0-rc4
- [BUG] fixes issue with postgres sync and enums [#1020](https://github.com/sequelize/sequelize/issues/1020) - [BUG] fixes issue with postgres sync and enums [#1020](https://github.com/sequelize/sequelize/issues/1020)
......
...@@ -604,19 +604,12 @@ module.exports = (function() { ...@@ -604,19 +604,12 @@ module.exports = (function() {
, includeWhere = {} , includeWhere = {}
, whereOptions = Utils._.clone(options) , whereOptions = Utils._.clone(options)
whereOptions.keysEscaped = true
if (tableName !== parentTable) { if (tableName !== parentTable) {
as = parentTable+'.'+include.as as = parentTable+'.'+include.as
} }
if (include.where) {
for (var key in include.where) {
if (include.where.hasOwnProperty(key)) {
includeWhere[self.quoteIdentifier(as)+'.'+self.quoteIdentifiers(key)] = include.where[key]
}
}
whereOptions.keysEscaped = true
}
// includeIgnoreAttributes is used by aggregate functions // includeIgnoreAttributes is used by aggregate functions
if (options.includeIgnoreAttributes !== false) { if (options.includeIgnoreAttributes !== false) {
attributes = include.attributes.map(function(attr) { attributes = include.attributes.map(function(attr) {
...@@ -677,7 +670,7 @@ module.exports = (function() { ...@@ -677,7 +670,7 @@ module.exports = (function() {
if (include.where) { if (include.where) {
targetWhere = self.hashToWhereConditions(includeWhere, include.daoFactory, whereOptions) targetWhere = self.getWhereConditions(include.where, self.sequelize.literal(self.quoteIdentifier(as)), include.daoFactory, whereOptions)
joinQueryItem += " AND "+ targetWhere joinQueryItem += " AND "+ targetWhere
if (subQuery) { if (subQuery) {
if (!options.where) options.where = {} if (!options.where) options.where = {}
...@@ -711,7 +704,7 @@ module.exports = (function() { ...@@ -711,7 +704,7 @@ module.exports = (function() {
joinQueryItem += where joinQueryItem += where
if (include.where) { if (include.where) {
joinQueryItem += " AND "+self.hashToWhereConditions(includeWhere, include.daoFactory, whereOptions) joinQueryItem += " AND "+self.getWhereConditions(include.where, self.sequelize.literal(self.quoteIdentifier(as)), include.daoFactory, whereOptions)
// If its a multi association we need to add a where query to the main where (executed in the subquery) // If its a multi association we need to add a where query to the main where (executed in the subquery)
if (subQuery && association.isMultiAssociation) { if (subQuery && association.isMultiAssociation) {
...@@ -890,8 +883,9 @@ module.exports = (function() { ...@@ -890,8 +883,9 @@ module.exports = (function() {
, where = {} , where = {}
, self = this , self = this
if (typeof prepend === 'undefined') if (typeof prepend === 'undefined') {
prepend = true prepend = true
}
if ((smth instanceof Utils.and) || (smth instanceof Utils.or)) { if ((smth instanceof Utils.and) || (smth instanceof Utils.or)) {
var connector = (smth instanceof Utils.and) ? ' AND ' : ' OR ' var connector = (smth instanceof Utils.and) ? ' AND ' : ' OR '
...@@ -903,8 +897,8 @@ module.exports = (function() { ...@@ -903,8 +897,8 @@ module.exports = (function() {
result = "(" + result + ")" result = "(" + result + ")"
} else if (Utils.isHash(smth)) { } else if (Utils.isHash(smth)) {
if (prepend) { if (prepend) {
smth = Utils.prependTableNameToHash(tableName, smth) smth = Utils.prependTableNameToHash(tableName, smth, self.quoteIdentifier.bind(self))
} }
result = this.hashToWhereConditions(smth, factory, options) result = this.hashToWhereConditions(smth, factory, options)
} else if (typeof smth === 'number') { } else if (typeof smth === 'number') {
var primaryKeys = !!factory ? Object.keys(factory.primaryKeys) : [] var primaryKeys = !!factory ? Object.keys(factory.primaryKeys) : []
......
...@@ -445,7 +445,7 @@ var Utils = module.exports = { ...@@ -445,7 +445,7 @@ var Utils = module.exports = {
return result return result
}, },
prependTableNameToHash: function(tableName, hash) { prependTableNameToHash: function(tableName, hash, quote) {
if (tableName) { if (tableName) {
var _hash = {} var _hash = {}
...@@ -453,7 +453,11 @@ var Utils = module.exports = { ...@@ -453,7 +453,11 @@ var Utils = module.exports = {
if (key instanceof Utils.literal) { if (key instanceof Utils.literal) {
_hash[key] = hash[key] _hash[key] = hash[key]
} else if (key.indexOf('.') === -1) { } else if (key.indexOf('.') === -1) {
_hash[tableName + '.' + key] = hash[key] if (tableName instanceof Utils.literal) {
_hash[tableName + '.' + quote(key)] = hash[key]
} else {
_hash[tableName + '.' + key] = hash[key]
}
} else { } else {
_hash[key] = hash[key] _hash[key] = hash[key]
} }
......
...@@ -514,6 +514,110 @@ describe(Support.getTestDialectTeaser("Include"), function () { ...@@ -514,6 +514,110 @@ describe(Support.getTestDialectTeaser("Include"), function () {
}) })
}) })
describe('where', function () {
it('should support Sequelize.and()', function (done) {
var User = this.sequelize.define('User', {})
, Item = this.sequelize.define('Item', {'test': DataTypes.STRING})
User.hasOne(Item);
Item.belongsTo(User);
this.sequelize.sync().done(function() {
async.auto({
users: function(callback) {
User.bulkCreate([{}, {}, {}]).done(function() {
User.findAll().done(callback)
})
},
items: function(callback) {
Item.bulkCreate([
{'test': 'abc'},
{'test': 'def'},
{'test': 'ghi'}
]).done(function() {
Item.findAll().done(callback)
})
},
associate: ['users', 'items', function(callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
var users = results.users
var items = results.items
chainer.add(users[0].setItem(items[0]))
chainer.add(users[1].setItem(items[1]))
chainer.add(users[2].setItem(items[2]))
chainer.run().done(callback)
}]
}, function() {
User.findAll({include: [
{model: Item, where: Sequelize.and({
test: 'def'
})}
]}).done(function(err, result) {
expect(err).not.to.be.ok
expect(result.length).to.eql(1)
expect(result[0].item.test).to.eql('def')
done()
})
})
})
})
it('should support Sequelize.or()', function (done) {
var User = this.sequelize.define('User', {})
, Item = this.sequelize.define('Item', {'test': DataTypes.STRING})
User.hasOne(Item);
Item.belongsTo(User);
this.sequelize.sync().done(function() {
async.auto({
users: function(callback) {
User.bulkCreate([{}, {}, {}]).done(function() {
User.findAll().done(callback)
})
},
items: function(callback) {
Item.bulkCreate([
{'test': 'abc'},
{'test': 'def'},
{'test': 'ghi'}
]).done(function() {
Item.findAll().done(callback)
})
},
associate: ['users', 'items', function(callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
var users = results.users
var items = results.items
chainer.add(users[0].setItem(items[0]))
chainer.add(users[1].setItem(items[1]))
chainer.add(users[2].setItem(items[2]))
chainer.run().done(callback)
}]
}, function() {
User.findAll({include: [
{model: Item, where: Sequelize.or({
test: 'def'
}, {
test: 'abc'
})}
]}).done(function(err, result) {
expect(err).not.to.be.ok
expect(result.length).to.eql(2)
done()
})
})
})
})
})
describe('findAndCountAll', function () { describe('findAndCountAll', function () {
it('should include associations to findAndCountAll', function(done) { it('should include associations to findAndCountAll', function(done) {
var User = this.sequelize.define('User', {}) var User = this.sequelize.define('User', {})
......
...@@ -1073,7 +1073,7 @@ describe(Support.getTestDialectTeaser("Include"), function () { ...@@ -1073,7 +1073,7 @@ describe(Support.getTestDialectTeaser("Include"), function () {
}) })
}) })
it('should be possible use limit and a where with a belongsTo include', function (done) { it('should be possible to use limit and a where with a belongsTo include', function (done) {
var User = this.sequelize.define('User', {}) var User = this.sequelize.define('User', {})
, Group = this.sequelize.define('Group', { , Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -1153,7 +1153,7 @@ describe(Support.getTestDialectTeaser("Include"), function () { ...@@ -1153,7 +1153,7 @@ describe(Support.getTestDialectTeaser("Include"), function () {
}) })
}) })
it('should be possible use limit and a where on a hasMany with additional includes', function (done) { it('should be possible to use limit and a where on a hasMany with additional includes', function (done) {
var self = this var self = this
this.fixtureA(function () { this.fixtureA(function () {
self.models.Product.findAll({ self.models.Product.findAll({
...@@ -1184,7 +1184,7 @@ describe(Support.getTestDialectTeaser("Include"), function () { ...@@ -1184,7 +1184,7 @@ describe(Support.getTestDialectTeaser("Include"), function () {
}) })
}) })
it('should be possible use limit and a where on a hasMany with a through model with additional includes', function (done) { it('should be possible to use limit and a where on a hasMany with a through model with additional includes', function (done) {
var self = this var self = this
this.fixtureA(function () { this.fixtureA(function () {
self.models.Product.findAll({ self.models.Product.findAll({
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!