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

Commit dda7306c by Mick Hansen

should be possible to extend the on clause with a where option on nested includes

1 parent 53566b28
...@@ -494,9 +494,24 @@ module.exports = (function() { ...@@ -494,9 +494,24 @@ module.exports = (function() {
, association = include.association , association = include.association
, through = include.through , through = include.through
, joinType = include.required ? ' INNER JOIN ' : ' LEFT OUTER JOIN ' , joinType = include.required ? ' INNER JOIN ' : ' LEFT OUTER JOIN '
, where = {}
, whereOptions = Utils._.clone(options)
if (tableName !== parentTable) as = parentTable+'.'+include.as if (tableName !== parentTable) as = parentTable+'.'+include.as
if (include.where) {
for (var key in include.where) {
if (include.where.hasOwnProperty(key)) {
where[self.quoteIdentifier(as)+'.'+self.quoteIdentifiers(key)] = include.where[key]
}
}
console.log(where)
include.where = where
whereOptions.keysEscaped = true
}
attributes = include.attributes.map(function(attr) { attributes = include.attributes.map(function(attr) {
return self.quoteIdentifier(as) + "." + self.quoteIdentifier(attr) + " AS " + self.quoteIdentifier(as + "." + attr) return self.quoteIdentifier(as) + "." + self.quoteIdentifier(attr) + " AS " + self.quoteIdentifier(as + "." + attr)
}) })
...@@ -531,7 +546,7 @@ module.exports = (function() { ...@@ -531,7 +546,7 @@ module.exports = (function() {
joinQueryItem += self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(identTarget) joinQueryItem += self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(identTarget)
if (include.where) { if (include.where) {
joinQueryItem += " AND "+self.getWhereConditions(include.where, as, include.daoFactory, options) joinQueryItem += " AND "+self.hashToWhereConditions(include.where, include.daoFactory, whereOptions)
} }
} else { } else {
var primaryKeysLeft = ((association.associationType === 'BelongsTo') ? Object.keys(association.target.primaryKeys) : Object.keys(include.association.source.primaryKeys)) var primaryKeysLeft = ((association.associationType === 'BelongsTo') ? Object.keys(association.target.primaryKeys) : Object.keys(include.association.source.primaryKeys))
...@@ -545,7 +560,7 @@ module.exports = (function() { ...@@ -545,7 +560,7 @@ module.exports = (function() {
joinQueryItem += self.quoteIdentifier(tableRight) + "." + self.quoteIdentifier(attrRight) joinQueryItem += self.quoteIdentifier(tableRight) + "." + self.quoteIdentifier(attrRight)
if (include.where) { if (include.where) {
joinQueryItem += " AND "+self.getWhereConditions(include.where, as, include.daoFactory, options) joinQueryItem += " AND "+self.hashToWhereConditions(include.where, include.daoFactory, whereOptions)
} }
} }
...@@ -832,16 +847,22 @@ module.exports = (function() { ...@@ -832,16 +847,22 @@ module.exports = (function() {
hashToWhereConditions: function(hash, dao, options) { hashToWhereConditions: function(hash, dao, options) {
var result = [] var result = []
options = options || {}
for (var key in hash) { for (var key in hash) {
var value = hash[key] var value = hash[key]
, _key , _key
, _value = null , _value = null
if (options.keysEscaped) {
_key = key
} else {
if(this.isAssociationFilter(key, dao, options)){ if(this.isAssociationFilter(key, dao, options)){
_key = key = this.getAssociationFilterColumn(key, dao, options); _key = key = this.getAssociationFilterColumn(key, dao, options);
} else { } else {
_key = this.quoteIdentifiers(key) _key = this.quoteIdentifiers(key)
} }
}
//handle qualified key names //handle qualified key names
......
...@@ -1165,6 +1165,183 @@ describe(Support.getTestDialectTeaser("Include"), function () { ...@@ -1165,6 +1165,183 @@ describe(Support.getTestDialectTeaser("Include"), function () {
}) })
}) })
}) })
it('should be possible to extend the on clause with a where option on nested includes', function (done) {
var User = this.sequelize.define('User', {})
, Product = this.sequelize.define('Product', {
title: DataTypes.STRING
})
, Tag = this.sequelize.define('Tag', {
name: DataTypes.STRING
})
, Price = this.sequelize.define('Price', {
value: DataTypes.FLOAT
})
, Customer = this.sequelize.define('Customer', {
name: DataTypes.STRING
})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
})
, GroupMember = this.sequelize.define('GroupMember', {
})
, Rank = this.sequelize.define('Rank', {
name: DataTypes.STRING,
canInvite: {
type: DataTypes.INTEGER,
defaultValue: 0
},
canRemove: {
type: DataTypes.INTEGER,
defaultValue: 0
}
})
User.hasMany(Product)
Product.belongsTo(User)
Product.hasMany(Tag)
Tag.hasMany(Product)
Product.belongsTo(Tag, {as: 'Category'})
Product.hasMany(Price)
Price.belongsTo(Product)
User.hasMany(GroupMember, {as: 'Memberships'})
GroupMember.belongsTo(User)
GroupMember.belongsTo(Rank)
GroupMember.belongsTo(Group)
Group.hasMany(GroupMember, {as: 'Memberships'})
this.sequelize.sync({force: true}).done(function () {
var count = 4
, i = -1
async.auto({
groups: function(callback) {
Group.bulkCreate([
{name: 'Developers'},
{name: 'Designers'}
]).done(function () {
Group.findAll().done(callback)
})
},
ranks: function(callback) {
Rank.bulkCreate([
{name: 'Admin', canInvite: 1, canRemove: 1},
{name: 'Member', canInvite: 1, canRemove: 0}
]).done(function () {
Rank.findAll().done(callback)
})
},
tags: function(callback) {
Tag.bulkCreate([
{name: 'A'},
{name: 'B'},
{name: 'C'}
]).done(function () {
Tag.findAll().done(callback)
})
},
loop: ['groups', 'ranks', 'tags', function (done, results) {
var groups = results.groups
, ranks = results.ranks
, tags = results.tags
async.whilst(
function () { return i < count; },
function (callback) {
i++
async.auto({
user: function (callback) {
User.create().done(callback)
},
memberships: ['user', function (callback, results) {
GroupMember.bulkCreate([
{UserId: results.user.id, GroupId: groups[0].id, RankId: ranks[0].id},
{UserId: results.user.id, GroupId: groups[1].id, RankId: ranks[1].id}
]).done(callback)
}],
products: function (callback) {
Product.bulkCreate([
{title: 'Chair'},
{title: 'Desk'}
]).done(function () {
Product.findAll().done(callback)
})
},
userProducts: ['user', 'products', function (callback, results) {
results.user.setProducts([
results.products[(i * 2)+0],
results.products[(i * 2)+1]
]).done(callback)
}],
productTags: ['products', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.products[(i * 2) + 0].setTags([
tags[0],
tags[2]
]))
chainer.add(results.products[(i * 2) + 1].setTags([
tags[1]
]))
chainer.add(results.products[(i * 2) + 0].setCategory(tags[1]))
chainer.run().done(callback)
}],
prices: ['products', function (callback, results) {
Price.bulkCreate([
{ProductId: results.products[(i * 2) + 0].id, value: 5},
{ProductId: results.products[(i * 2) + 0].id, value: 10},
{ProductId: results.products[(i * 2) + 1].id, value: 5},
{ProductId: results.products[(i * 2) + 1].id, value: 10},
{ProductId: results.products[(i * 2) + 1].id, value: 15},
{ProductId: results.products[(i * 2) + 1].id, value: 20}
]).done(callback)
}]
}, callback)
},
function (err) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: GroupMember, as: 'Memberships', include: [
Group,
{model: Rank, where: {name: 'Admin'}}
]},
{model: Product, include: [
Tag,
{model: Tag, as: 'Category'},
{model: Price, where: {
value: {
gt: 15
}
}}
]}
],
order: 'id ASC'
}).done(function (err, users) {
expect(err).not.to.be.ok
users.forEach(function (user) {
expect(user.memberships.length).to.equal(1)
expect(user.memberships[0].rank.name).to.equal('Admin')
expect(user.products.length).to.equal(1)
expect(user.products[0].prices.length).to.equal(1)
})
done()
})
}
)
}]
}, done)
})
})
}) })
describe('findAndCountAll', function () { describe('findAndCountAll', function () {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!