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

Commit e16a26f7 by joshm Committed by Mick Hansen

Add pg schema specific test sets

Bulk queries do not completely work with schemas, so
the test fixture may have issues.

all but the last 3 tests of findAll.ph.schema.test.js should pass
1 parent d603c8ac
...@@ -638,7 +638,7 @@ module.exports = (function() { ...@@ -638,7 +638,7 @@ module.exports = (function() {
if (options.include) { if (options.include) {
var generateJoinQueries = function(include, parentTable) { var generateJoinQueries = function(include, parentTable) {
var table = include.daoFactory.tableName var table = include.daoFactory.getTableName()
, as = include.as , as = include.as
, joinQueryItem = "" , joinQueryItem = ""
, joinQueries = { , joinQueries = {
...@@ -672,7 +672,7 @@ module.exports = (function() { ...@@ -672,7 +672,7 @@ module.exports = (function() {
} }
if (through) { if (through) {
var throughTable = through.daoFactory.tableName var throughTable = through.daoFactory.getTableName()
, throughAs = as + "." + through.as , throughAs = as + "." + through.as
, throughAttributes = through.attributes.map(function(attr) { , throughAttributes = through.attributes.map(function(attr) {
return self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(attr) + " AS " + self.quoteIdentifier(throughAs + "." + attr) return self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(attr) + " AS " + self.quoteIdentifier(throughAs + "." + attr)
...@@ -699,7 +699,7 @@ module.exports = (function() { ...@@ -699,7 +699,7 @@ module.exports = (function() {
// Filter statement for left side of through // Filter statement for left side of through
// Used by both join and subquery where // Used by both join and subquery where
sourceJoinOn = self.quoteIdentifier(tableSource) + "." + self.quoteIdentifier(attrSource) + " = " sourceJoinOn = self.quoteTable(tableSource) + "." + self.quoteIdentifier(attrSource) + " = "
sourceJoinOn += self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(identSource) sourceJoinOn += self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(identSource)
// Filter statement for right side of through // Filter statement for right side of through
...@@ -708,7 +708,7 @@ module.exports = (function() { ...@@ -708,7 +708,7 @@ module.exports = (function() {
targetJoinOn += self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(identTarget) targetJoinOn += self.quoteIdentifier(throughAs) + "." + self.quoteIdentifier(identTarget)
// Generate join SQL for left side of through // Generate join SQL for left side of through
joinQueryItem += joinType + self.quoteIdentifier(throughTable) + " AS " + self.quoteIdentifier(throughAs) + " ON " joinQueryItem += joinType + self.quoteTable(throughTable) + " AS " + self.quoteIdentifier(throughAs) + " ON "
joinQueryItem += sourceJoinOn joinQueryItem += sourceJoinOn
// Generate join SQL for right side of through // Generate join SQL for right side of through
...@@ -724,7 +724,7 @@ module.exports = (function() { ...@@ -724,7 +724,7 @@ module.exports = (function() {
// Creating the as-is where for the subQuery, checks that the required association exists // Creating the as-is where for the subQuery, checks that the required association exists
var _where = "("; var _where = "(";
_where += "SELECT "+self.quoteIdentifier(identSource)+" FROM " + self.quoteIdentifier(throughTable) + " AS " + self.quoteIdentifier(throughAs); _where += "SELECT "+self.quoteIdentifier(identSource)+" FROM " + self.quoteTable(throughTable) + " AS " + self.quoteIdentifier(throughAs);
_where += joinType + self.quoteTable(table) + " AS " + self.quoteIdentifier(as) + " ON "+targetJoinOn; _where += joinType + self.quoteTable(table) + " AS " + self.quoteIdentifier(as) + " ON "+targetJoinOn;
_where += " WHERE " + sourceJoinOn + " AND " + targetWhere + " LIMIT 1" _where += " WHERE " + sourceJoinOn + " AND " + targetWhere + " LIMIT 1"
_where += ")"; _where += ")";
...@@ -876,9 +876,33 @@ module.exports = (function() { ...@@ -876,9 +876,33 @@ module.exports = (function() {
// If using subQuery, select attributes from wrapped subQuery and join out join tables // If using subQuery, select attributes from wrapped subQuery and join out join tables
if (subQuery) { if (subQuery) {
//the subquery "AS" uses the tableName at the front of the SELECT (out of the subquery)
//as the "AS", when this is the case, force quoting on the mainAttributes "options.table"
//that will be used in the "AS".
var asTable = options.table
var aliasAttrs = mainAttributes[0].split('.')
if(aliasAttrs.length > 1) {
var baseName = aliasAttrs[0]+'.'+aliasAttrs[1]
//here is the match from subquery to mainAttributes
if(baseName === options.table) {
var aliasAttrs = mainAttributes[0].split('.')
var remainingVals = Utils._.rest(aliasAttrs, 2)
//only add back the rest if it exists
if(remainingVals.length) {
mainAttributes[0] = self.quoteIdentifier(baseName, true)+'.'+remainingVals.join('.')
} else {
mainAttributes[0] = self.quoteIdentifier(baseName, true)
}
//quote the "as"
asTable = self.quoteIdentifier(options.table, true)
}
}
query = "SELECT " + mainAttributes.join(', ') + " FROM (" query = "SELECT " + mainAttributes.join(', ') + " FROM ("
query += subQueryItems.join('') query += subQueryItems.join('')
query += ") AS "+options.table query += ") AS "+asTable
query += mainJoinQueries.join('') query += mainJoinQueries.join('')
query += mainQueryItems.join('') query += mainQueryItems.join('')
} else { } else {
......
...@@ -279,7 +279,7 @@ module.exports = (function() { ...@@ -279,7 +279,7 @@ module.exports = (function() {
}.bind(this)) }.bind(this))
var replacements = { var replacements = {
table: this.quoteIdentifiers(tableName) table: this.quoteTable(tableName)
, attributes: allAttributes.map(function(attr){ , attributes: allAttributes.map(function(attr){
return this.quoteIdentifier(attr) return this.quoteIdentifier(attr)
}.bind(this)).join(",") }.bind(this)).join(",")
......
/* jshint camelcase: false */
/* jshint expr: true */
var chai = require('chai')
, Sequelize = require('../../index')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + "/../../lib/data-types")
, dialect = Support.getTestDialect()
, config = require(__dirname + "/../config/config")
, sinon = require('sinon')
, datetime = require('chai-datetime')
, _ = require('lodash')
, moment = require('moment')
, async = require('async')
chai.use(datetime)
chai.Assertion.includeStack = true
var sortById = function(a, b) {
return a.id < b.id ? -1 : 1
}
if (dialect.match(/^postgres/)) {
describe(Support.getTestDialectTeaser("Schema Based PG Include"), function () {
describe('findAll', function () {
beforeEach(function () {
var self = this
this.sequelize.options.logging = console.log
this.fixtureA = function(done) {
self.sequelize.dropAllSchemas().success(function(){
self.sequelize.createSchema("account").success(function(){
var AccUser = self.sequelize.define("AccUser", {}, {schema: "account"})
, Company = self.sequelize.define("Company", {
name: DataTypes.STRING
}, {schema: "account"})
, Product = self.sequelize.define("Product", {
title: DataTypes.STRING
}, {schema: "account"})
, Tag = self.sequelize.define("Tag", {
name: DataTypes.STRING
}, {schema: "account"})
, Price = self.sequelize.define("Price", {
value: DataTypes.FLOAT
}, {schema: "account"})
, Customer = self.sequelize.define("Customer", {
name: DataTypes.STRING
}, {schema: "account"})
, Group = self.sequelize.define("Group", {
name: DataTypes.STRING
}, {schema: "account"})
, GroupMember = self.sequelize.define("GroupMember", {
}, {schema: "account"})
, Rank = self.sequelize.define("Rank", {
name: DataTypes.STRING,
canInvite: {
type: DataTypes.INTEGER,
defaultValue: 0
},
canRemove: {
type: DataTypes.INTEGER,
defaultValue: 0
},
canPost: {
type: DataTypes.INTEGER,
defaultValue: 0
}
}, {schema: "account"})
self.models = {
AccUser: AccUser,
Company: Company,
Product: Product,
Tag: Tag,
Price: Price,
Customer: Customer,
Group: Group,
GroupMember: GroupMember,
Rank: Rank
}
AccUser.hasMany(Product)
Product.belongsTo(AccUser)
Product.hasMany(Tag)
Tag.hasMany(Product)
Product.belongsTo(Tag, {as: 'Category'})
Product.belongsTo(Company)
Product.hasMany(Price)
Price.belongsTo(Product)
AccUser.hasMany(GroupMember, {as: 'Memberships'})
GroupMember.belongsTo(AccUser)
GroupMember.belongsTo(Rank)
GroupMember.belongsTo(Group)
Group.hasMany(GroupMember, {as: 'Memberships'})
self.sequelize.sync({force: true}).done(function () {
console.log("DONE WITH SYNC")
var count = 4
, i = -1
async.auto({
groups: function(callback) {
Group.bulkCreate([
{name: 'Developers'},
{name: 'Designers'},
{name: 'Managers'}
]).done(function () {
Group.findAll().done(callback)
})
},
companies: function(callback) {
Company.bulkCreate([
{name: 'Sequelize'},
{name: 'Coca Cola'},
{name: 'Bonanza'},
{name: 'NYSE'},
{name: 'Coshopr'}
]).done(function (err) {
if (err) return callback(err);
Company.findAll().done(callback)
})
},
ranks: function(callback) {
Rank.bulkCreate([
{name: 'Admin', canInvite: 1, canRemove: 1, canPost: 1},
{name: 'Trustee', canInvite: 1, canRemove: 0, canPost: 1},
{name: 'Member', canInvite: 1, canRemove: 0, canPost: 0}
]).done(function (err) {
Rank.findAll().done(callback)
})
},
tags: function(callback) {
Tag.bulkCreate([
{name: 'A'},
{name: 'B'},
{name: 'C'},
{name: 'D'},
{name: 'E'}
]).done(function () {
Tag.findAll().done(callback)
})
},
loop: ['groups', 'ranks', 'tags', 'companies', function (done, results) {
var groups = results.groups
, ranks = results.ranks
, tags = results.tags
, companies = results.companies
async.whilst(
function () { return i < count; },
function (callback) {
i++
async.auto({
user: function (callback) {
AccUser.create().done(callback)
},
memberships: ['user', function (callback, results) {
var groupMembers = [
{AccUserId: results.user.id, GroupId: groups[0].id, RankId: ranks[0].id},
{AccUserId: results.user.id, GroupId: groups[1].id, RankId: ranks[2].id}
]
if (i < 3) {
groupMembers.push({AccUserId: results.user.id, GroupId: groups[2].id, RankId: ranks[1].id})
}
GroupMember.bulkCreate(groupMembers).done(callback)
}],
products: function (callback) {
Product.bulkCreate([
{title: 'Chair'},
{title: 'Desk'},
{title: 'Bed'},
{title: 'Pen'},
{title: 'Monitor'}
]).done(function (err) {
if (err) return callback(err);
Product.findAll().done(callback)
})
},
userProducts: ['user', 'products', function (callback, results) {
results.user.setProducts([
results.products[(i * 5)+0],
results.products[(i * 5)+1],
results.products[(i * 5)+3]
]).done(callback)
}],
productTags: ['products', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.products[(i * 5) + 0].setTags([
tags[0],
tags[2]
]))
chainer.add(results.products[(i * 5) + 1].setTags([
tags[1]
]))
chainer.add(results.products[(i * 5) + 0].setCategory(tags[1]))
chainer.add(results.products[(i * 5) + 2].setTags([
tags[0]
]))
chainer.add(results.products[(i * 5) + 3].setTags([
tags[0]
]))
chainer.run().done(callback)
}],
companies: ['products', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
results.products[(i * 5)+0].setCompany(companies[4])
results.products[(i * 5)+1].setCompany(companies[3])
results.products[(i * 5)+2].setCompany(companies[2])
results.products[(i * 5)+3].setCompany(companies[1])
results.products[(i * 5)+4].setCompany(companies[0])
chainer.run().done(callback)
}],
prices: ['products', function (callback, results) {
Price.bulkCreate([
{ProductId: results.products[(i * 5) + 0].id, value: 5},
{ProductId: results.products[(i * 5) + 0].id, value: 10},
{ProductId: results.products[(i * 5) + 1].id, value: 5},
{ProductId: results.products[(i * 5) + 1].id, value: 10},
{ProductId: results.products[(i * 5) + 1].id, value: 15},
{ProductId: results.products[(i * 5) + 1].id, value: 20},
{ProductId: results.products[(i * 5) + 2].id, value: 20},
{ProductId: results.products[(i * 5) + 3].id, value: 20}
]).done(callback)
}]
}, callback)
},
function (err) {
expect(err).not.to.be.ok
done()
}
)
}]
}, done.bind(this))
}).error(function(err) {
console.log("e: ", err)
}).success(function(s) {
console.log("s: ", s)
}).sql(function(sql) {
console.log("sql: ", sql)
})
})
})
}
})
it('should support an include with multiple different association types', function (done) {
var self = this
this.sequelize.options.logging = console.log
self.sequelize.dropAllSchemas().success(function(){
self.sequelize.createSchema("account").success(function(){
var AccUser = self.sequelize.define("AccUser", {}, {schema: "account"})
, Product = self.sequelize.define("Product", {
title: DataTypes.STRING
}, {schema: "account"})
, Tag = self.sequelize.define("Tag", {
name: DataTypes.STRING
}, {schema: "account"})
, Price = self.sequelize.define("Price", {
value: DataTypes.FLOAT
}, {schema: "account"})
, Customer = self.sequelize.define("Customer", {
name: DataTypes.STRING
}, {schema: "account"})
, Group = self.sequelize.define("Group", {
name: DataTypes.STRING
}, {schema: "account"})
, GroupMember = self.sequelize.define("GroupMember", {
}, {schema: "account"})
, Rank = self.sequelize.define("Rank", {
name: DataTypes.STRING,
canInvite: {
type: DataTypes.INTEGER,
defaultValue: 0
},
canRemove: {
type: DataTypes.INTEGER,
defaultValue: 0
}
}, {schema: "account"})
AccUser.hasMany(Product)
Product.belongsTo(AccUser)
Product.hasMany(Tag)
Tag.hasMany(Product)
Product.belongsTo(Tag, {as: 'Category'})
Product.hasMany(Price)
Price.belongsTo(Product)
AccUser.hasMany(GroupMember, {as: 'Memberships'})
GroupMember.belongsTo(AccUser)
GroupMember.belongsTo(Rank)
GroupMember.belongsTo(Group)
Group.hasMany(GroupMember, {as: 'Memberships'})
self.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) {
AccUser.create().done(callback)
},
memberships: ['user', function (callback, results) {
GroupMember.bulkCreate([
{AccUserId: results.user.id, GroupId: groups[0].id, RankId: ranks[0].id},
{AccUserId: 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
AccUser.findAll({
include: [
{model: GroupMember, as: 'Memberships', include: [
Group,
Rank
]},
{model: Product, include: [
Tag,
{model: Tag, as: 'Category'},
Price
]}
],
order: [
['AccUsers.id', 'ASC']
]
}).done(function (err, users) {
expect(err).not.to.be.ok
users.forEach(function (user, i) {
user.memberships.sort(sortById)
expect(user.memberships.length).to.equal(2)
expect(user.memberships[0].group.name).to.equal('Developers')
expect(user.memberships[0].rank.canRemove).to.equal(1)
expect(user.memberships[1].group.name).to.equal('Designers')
expect(user.memberships[1].rank.canRemove).to.equal(0)
user.products.sort(sortById)
expect(user.products.length).to.equal(2)
expect(user.products[0].tags.length).to.equal(2)
expect(user.products[1].tags.length).to.equal(1)
expect(user.products[0].category).to.be.ok
expect(user.products[1].category).not.to.be.ok
expect(user.products[0].prices.length).to.equal(2)
expect(user.products[1].prices.length).to.equal(4)
done()
})
})
}
)
}]
}, done)
}).error(function(err) {
console.log(err)
})
})
})
})
it('should support many levels of belongsTo', function (done) {
var A = this.sequelize.define('A', {}, {schema: "account"})
, B = this.sequelize.define('B', {}, {schema: "account"})
, C = this.sequelize.define('C', {}, {schema: "account"})
, D = this.sequelize.define('D', {}, {schema: "account"})
, E = this.sequelize.define('E', {}, {schema: "account"})
, F = this.sequelize.define('F', {}, {schema: "account"})
, G = this.sequelize.define('G', {}, {schema: "account"})
, H = this.sequelize.define('H', {}, {schema: "account"})
A.belongsTo(B)
B.belongsTo(C)
C.belongsTo(D)
D.belongsTo(E)
E.belongsTo(F)
F.belongsTo(G)
G.belongsTo(H)
var b, singles = [
B,
C,
D,
E,
F,
G,
H
]
this.sequelize.sync().done(function () {
async.auto({
as: function (callback) {
A.bulkCreate([
{},
{},
{},
{},
{},
{},
{},
{}
]).done(function () {
A.findAll().done(callback)
})
},
singleChain: function (callback) {
var previousInstance
, previousModel
async.eachSeries(singles, function (model, callback, i) {
model.create({}).done(function (err, instance) {
if (previousInstance) {
previousInstance["set"+model.name](instance).done(function () {
previousInstance = instance
callback()
})
} else {
previousInstance = b = instance
callback()
}
})
}, callback)
},
abs: ['as', 'singleChain', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
results.as.forEach(function (a) {
chainer.add(a.setB(b))
})
chainer.run().done(callback)
}]
}, function () {
A.findAll({
include: [
{model: B, include: [
{model: C, include: [
{model: D, include: [
{model: E, include: [
{model: F, include: [
{model: G, include: [
{model: H}
]}
]}
]}
]}
]}
]}
]
}).done(function (err, as) {
expect(err).not.to.be.ok
expect(as.length).to.be.ok
as.forEach(function (a) {
expect(a.b.c.d.e.f.g.h).to.be.ok
})
done()
})
})
})
})
it('should support ordering with only belongsTo includes', function(done) {
var User = this.sequelize.define('SpecialUser', {}, {schema: "account"})
, Item = this.sequelize.define('Item', {'test': DataTypes.STRING}, {schema: "account"})
, Order = this.sequelize.define('Order', {'position': DataTypes.INTEGER}, {schema: "account"})
User.belongsTo(Item, {'as': 'itemA', foreignKey: 'itemA_id'})
User.belongsTo(Item, {'as': 'itemB', foreignKey: 'itemB_id'})
User.belongsTo(Order)
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'},
{'test': 'jkl'}
]).done(function() {
Item.findAll({order: ['id']}).done(callback)
})
},
orders: function(callback) {
Order.bulkCreate([
{'position': 2},
{'position': 3},
{'position': 1}
]).done(function() {
Order.findAll({order: ['id']}).done(callback)
})
},
associate: ['users', 'items', 'orders', function(callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
var user1 = results.users[0]
var user2 = results.users[1]
var user3 = results.users[2]
var item1 = results.items[0]
var item2 = results.items[1]
var item3 = results.items[2]
var item4 = results.items[3]
var order1 = results.orders[0]
var order2 = results.orders[1]
var order3 = results.orders[2]
chainer.add(user1.setItemA(item1))
chainer.add(user1.setItemB(item2))
chainer.add(user1.setOrder(order3))
chainer.add(user2.setItemA(item3))
chainer.add(user2.setItemB(item4))
chainer.add(user2.setOrder(order2))
chainer.add(user3.setItemA(item1))
chainer.add(user3.setItemB(item4))
chainer.add(user3.setOrder(order1))
chainer.run().done(callback)
}]
}, function() {
User.findAll({
'where': {'itemA.test': 'abc'},
'include': [
{'model': Item, 'as': 'itemA'},
{'model': Item, 'as': 'itemB'},
Order],
'order': ['Order.position']
}).done(function(err, as) {
expect(err).not.to.be.ok
expect(as.length).to.eql(2)
expect(as[0].itemA.test).to.eql('abc')
expect(as[1].itemA.test).to.eql('abc')
expect(as[0].order.position).to.eql(1)
expect(as[1].order.position).to.eql(2)
done()
})
})
})
})
it('should include attributes from through models', function (done) {
var Product = this.sequelize.define('Product', {
title: DataTypes.STRING
}, {schema: "account"})
, Tag = this.sequelize.define('Tag', {
name: DataTypes.STRING
}, {schema: "account"})
, ProductTag = this.sequelize.define('ProductTag', {
priority: DataTypes.INTEGER
}, {schema: "account"})
Product.hasMany(Tag, {through: ProductTag})
Tag.hasMany(Product, {through: ProductTag})
this.sequelize.sync({force: true}).done(function () {
async.auto({
products: function (callback) {
Product.bulkCreate([
{title: 'Chair'},
{title: 'Desk'},
{title: 'Dress'}
]).done(function () {
Product.findAll().done(callback)
})
},
tags: function(callback) {
Tag.bulkCreate([
{name: 'A'},
{name: 'B'},
{name: 'C'}
]).done(function () {
Tag.findAll().done(callback)
})
},
productTags: ['products', 'tags', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.products[0].addTag(results.tags[0], {priority: 1}))
chainer.add(results.products[0].addTag(results.tags[1], {priority: 2}))
chainer.add(results.products[1].addTag(results.tags[1], {priority: 1}))
chainer.add(results.products[2].addTag(results.tags[0], {priority: 3}))
chainer.add(results.products[2].addTag(results.tags[1], {priority: 1}))
chainer.add(results.products[2].addTag(results.tags[2], {priority: 2}))
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
Product.findAll({
include: [
{model: Tag}
],
order: [
['id', 'ASC'],
['Tags.id', 'ASC']
]
}).done(function (err, products) {
expect(err).not.to.be.ok
expect(products[0].tags[0].productTag.priority).to.equal(1)
expect(products[0].tags[1].productTag.priority).to.equal(2)
expect(products[1].tags[0].productTag.priority).to.equal(1)
expect(products[2].tags[0].productTag.priority).to.equal(3)
expect(products[2].tags[1].productTag.priority).to.equal(1)
expect(products[2].tags[2].productTag.priority).to.equal(2)
done()
})
})
})
})
it('should support a required belongsTo include', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Group = this.sequelize.define('Group', {}, {schema: "account"})
User.belongsTo(Group)
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([{}, {}]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}, {}]).done(function () {
User.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
results.users[2].setGroup(results.groups[1]).done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, required: true}
]
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(1)
expect(users[0].group).to.be.ok
done()
})
})
})
})
it('should be possible to extend the on clause with a where option on a belongsTo include', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
User.belongsTo(Group)
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([
{name: 'A'},
{name: 'B'}
]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}]).done(function () {
User.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[0].setGroup(results.groups[1]))
chainer.add(results.users[1].setGroup(results.groups[0]))
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, where: {name: 'A'}}
]
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(1)
expect(users[0].group).to.be.ok
expect(users[0].group.name).to.equal('A')
done()
})
})
})
})
it('should be possible to extend the on clause with a where option on a belongsTo include', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
User.belongsTo(Group)
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([
{name: 'A'},
{name: 'B'}
]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}]).done(function () {
User.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[0].setGroup(results.groups[1]))
chainer.add(results.users[1].setGroup(results.groups[0]))
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, required: true}
]
}).done(function (err, users) {
expect(err).not.to.be.ok
users.forEach(function (user) {
expect(user.group).to.be.ok
})
done()
})
})
})
})
it('should be possible to define a belongsTo include as required with child hasMany with limit', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"}) , Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
, Category = this.sequelize.define('Category', {
category: DataTypes.STRING
}, {schema: "account"})
User.belongsTo(Group)
Group.hasMany(Category)
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([
{name: 'A'},
{name: 'B'}
]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}]).done(function () {
User.findAll().done(callback)
})
},
categories: function (callback) {
Category.bulkCreate([{}, {}]).done(function () {
Category.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[0].setGroup(results.groups[1]))
chainer.add(results.users[1].setGroup(results.groups[0]))
chainer.run().done(callback)
}],
groupCategories: ['groups', 'categories', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
results.groups.forEach(function (group) {
chainer.add(group.setCategories(results.categories))
})
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, required: true, include: [
{model: Category}
]}
],
limit: 1
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(1)
users.forEach(function (user) {
expect(user.group).to.be.ok
expect(user.group.categories).to.be.ok
})
done()
})
})
})
})
it('should be possible to define a belongsTo include as required with child hasMany with limit and aliases', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
, Category = this.sequelize.define('Category', {
category: DataTypes.STRING
}, {schema: "account"})
User.belongsTo(Group, {as: 'Team'})
Group.hasMany(Category, {as: 'Tags'})
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([
{name: 'A'},
{name: 'B'}
]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}]).done(function () {
User.findAll().done(callback)
})
},
categories: function (callback) {
Category.bulkCreate([{}, {}]).done(function () {
Category.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[0].setTeam(results.groups[1]))
chainer.add(results.users[1].setTeam(results.groups[0]))
chainer.run().done(callback)
}],
groupCategories: ['groups', 'categories', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
results.groups.forEach(function (group) {
chainer.add(group.setTags(results.categories))
})
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, required: true, as: 'Team', include: [
{model: Category, as: 'Tags'}
]}
],
limit: 1
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(1)
users.forEach(function (user) {
expect(user.team).to.be.ok
expect(user.team.tags).to.be.ok
})
done()
})
})
})
})
it('should be possible to define a belongsTo include as required with child hasMany which is not required with limit', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
, Category = this.sequelize.define('Category', {
category: DataTypes.STRING
}, {schema: "account"})
User.belongsTo(Group)
Group.hasMany(Category)
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([
{name: 'A'},
{name: 'B'}
]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}]).done(function () {
User.findAll().done(callback)
})
},
categories: function (callback) {
Category.bulkCreate([{}, {}]).done(function () {
Category.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[0].setGroup(results.groups[1]))
chainer.add(results.users[1].setGroup(results.groups[0]))
chainer.run().done(callback)
}],
groupCategories: ['groups', 'categories', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
results.groups.forEach(function (group) {
chainer.add(group.setCategories(results.categories))
})
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, required: true, include: [
{model: Category, required: false}
]}
],
limit: 1
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(1)
users.forEach(function (user) {
expect(user.group).to.be.ok
expect(user.group.categories).to.be.ok
})
done()
})
})
})
})
it('should be possible to extend the on clause with a where option on a hasOne include', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Project = this.sequelize.define('Project', {
title: DataTypes.STRING
}, {schema: "account"})
User.hasOne(Project, {as: 'LeaderOf'})
this.sequelize.sync({force: true}).done(function () {
async.auto({
projects: function (callback) {
Project.bulkCreate([
{title: 'Alpha'},
{title: 'Beta'}
]).done(function () {
Project.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}]).done(function () {
User.findAll().done(callback)
})
},
userProjects: ['users', 'projects', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[1].setLeaderOf(results.projects[1]))
chainer.add(results.users[0].setLeaderOf(results.projects[0]))
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Project, as: 'LeaderOf', where: {title: 'Beta'}}
]
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(1)
expect(users[0].leaderOf).to.be.ok
expect(users[0].leaderOf.title).to.equal('Beta')
done()
})
})
})
})
it('should be possible to extend the on clause with a where option on a hasMany include with a through model', function (done) {
var Product = this.sequelize.define('Product', {
title: DataTypes.STRING
}, {schema: "account"})
, Tag = this.sequelize.define('Tag', {
name: DataTypes.STRING
}, {schema: "account"})
, ProductTag = this.sequelize.define('ProductTag', {
priority: DataTypes.INTEGER
}, {schema: "account"})
Product.hasMany(Tag, {through: ProductTag})
Tag.hasMany(Product, {through: ProductTag})
this.sequelize.sync({force: true}).done(function () {
async.auto({
products: function (callback) {
Product.bulkCreate([
{title: 'Chair'},
{title: 'Desk'},
{title: 'Dress'}
]).done(function () {
Product.findAll().done(callback)
})
},
tags: function(callback) {
Tag.bulkCreate([
{name: 'A'},
{name: 'B'},
{name: 'C'}
]).done(function () {
Tag.findAll().done(callback)
})
},
productTags: ['products', 'tags', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.products[0].addTag(results.tags[0], {priority: 1}))
chainer.add(results.products[0].addTag(results.tags[1], {priority: 2}))
chainer.add(results.products[1].addTag(results.tags[1], {priority: 1}))
chainer.add(results.products[2].addTag(results.tags[0], {priority: 3}))
chainer.add(results.products[2].addTag(results.tags[1], {priority: 1}))
chainer.add(results.products[2].addTag(results.tags[2], {priority: 2}))
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
Product.findAll({
include: [
{model: Tag, where: {name: 'C'}}
]
}).done(function (err, products) {
expect(err).not.to.be.ok
expect(products.length).to.equal(1)
expect(products[0].tags.length).to.equal(1)
done()
})
})
})
})
it('should be possible to extend the on clause with a where option on nested includes', function (done) {
var User = this.sequelize.define('User', {
name: DataTypes.STRING
}, {schema: "account"})
, Product = this.sequelize.define('Product', {
title: DataTypes.STRING
}, {schema: "account"})
, Tag = this.sequelize.define('Tag', {
name: DataTypes.STRING
}, {schema: "account"})
, Price = this.sequelize.define('Price', {
value: DataTypes.FLOAT
}, {schema: "account"})
, Customer = this.sequelize.define('Customer', {
name: DataTypes.STRING
}, {schema: "account"})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
, GroupMember = this.sequelize.define('GroupMember', {
}, {schema: "account"})
, Rank = this.sequelize.define('Rank', {
name: DataTypes.STRING,
canInvite: {
type: DataTypes.INTEGER,
defaultValue: 0
},
canRemove: {
type: DataTypes.INTEGER,
defaultValue: 0
}
}, {schema: "account"})
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({name: 'FooBarzz'}).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)
})
})
it('should be possible to use limit and a where with a belongsTo include', function (done) {
var User = this.sequelize.define('User', {}, {schema: "account"})
, Group = this.sequelize.define('Group', {
name: DataTypes.STRING
}, {schema: "account"})
User.belongsTo(Group)
this.sequelize.sync({force: true}).done(function () {
async.auto({
groups: function (callback) {
Group.bulkCreate([
{name: 'A'},
{name: 'B'},
]).done(function () {
Group.findAll().done(callback)
})
},
users: function (callback) {
User.bulkCreate([{}, {}, {}, {}]).done(function () {
User.findAll().done(callback)
})
},
userGroups: ['users', 'groups', function (callback, results) {
var chainer = new Sequelize.Utils.QueryChainer()
chainer.add(results.users[0].setGroup(results.groups[0]))
chainer.add(results.users[1].setGroup(results.groups[0]))
chainer.add(results.users[2].setGroup(results.groups[0]))
chainer.add(results.users[3].setGroup(results.groups[1]))
chainer.run().done(callback)
}]
}, function (err, results) {
expect(err).not.to.be.ok
User.findAll({
include: [
{model: Group, where: {name: 'A'}}
],
limit: 2
}).done(function (err, users) {
expect(err).not.to.be.ok
expect(users.length).to.equal(2)
users.forEach(function (user) {
expect(user.group.name).to.equal('A')
})
done()
})
})
})
})
/
it('should be possible use limit, attributes and a where on a belongsTo with additional hasMany includes', function (done) {
var self = this
this.fixtureA(function () {
self.models.Product.findAll({
attributes: ['title'],
include: [
{model: self.models.Company, where: {name: 'NYSE'}},
{model: self.models.Tag},
{model: self.models.Price}
],
limit: 3,
order: [
[self.sequelize.col(self.models.Product.tableName+'.id'), 'ASC']
]
}).done(function (err, products) {
expect(err).not.to.be.ok
expect(products.length).to.equal(3)
products.forEach(function (product) {
expect(product.company.name).to.equal('NYSE')
expect(product.tags.length).to.be.ok
expect(product.prices.length).to.be.ok
})
done()
})
})
})
it('should be possible to use limit and a where on a hasMany with additional includes', function (done) {
var self = this
this.fixtureA(function () {
self.models.Product.findAll({
include: [
{model: self.models.Company},
{model: self.models.Tag},
{model: self.models.Price, where: {
value: {gt: 5}
}}
],
limit: 6,
order: 'id ASC'
}).done(function (err, products) {
expect(err).not.to.be.ok
expect(products.length).to.equal(6)
products.forEach(function (product) {
expect(product.tags.length).to.be.ok
expect(product.prices.length).to.be.ok
product.prices.forEach(function (price) {
expect(price.value).to.be.above(5)
})
})
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
this.fixtureA(function () {
self.models.Product.findAll({
include: [
{model: self.models.Company},
{model: self.models.Tag, where: {name: ['A', 'B','C']}},
{model: self.models.Price}
],
limit: 10,
order: 'id ASC'
}).done(function (err, products) {
expect(err).not.to.be.ok
expect(products.length).to.equal(10)
products.forEach(function (product) {
expect(product.tags.length).to.be.ok
expect(product.prices.length).to.be.ok
product.tags.forEach(function (tag) {
expect(['A', 'B', 'C']).to.include(tag.name)
})
})
done()
})
})
})
it('should support including date fields, with the correct timeszone', function (done) {
var User = this.sequelize.define('user', {
dateField: Sequelize.DATE
}, {timestamps: false, schema: "account"})
, Group = this.sequelize.define('group', {
dateField: Sequelize.DATE
}, {timestamps: false, schema: "account"})
User.hasMany(Group)
Group.hasMany(User)
this.sequelize.sync().success(function () {
User.create({ dateField: Date.UTC(2014, 1, 20) }).success(function (user) {
Group.create({ dateField: Date.UTC(2014, 1, 20) }).success(function (group) {
user.addGroup(group).success(function () {
User.findAll({
where: {
id: user.id
},
include: [Group]
}).success(function (users) {
expect(users[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20))
expect(users[0].groups[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20))
done()
})
})
})
})
})
})
})
})
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!