Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
public
/
sequelize
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
不要怂,就是干,撸起袖子干!
Commit 7df710b8
authored
Jan 05, 2014
by
Mick Hansen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First subQuery refactoring
1 parent
f150a0f7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
114 additions
and
867 deletions
lib/dao-factory.js
lib/dialects/abstract/query-generator.js
lib/dialects/mysql/query-generator.js
lib/dialects/postgres/query-generator.js
lib/dialects/sqlite/query-generator.js
test/associations/multiple-level-filters.test.js
test/include.test.js
lib/dao-factory.js
View file @
7df710b
...
@@ -1280,11 +1280,15 @@ module.exports = (function() {
...
@@ -1280,11 +1280,15 @@ module.exports = (function() {
options
.
include
=
options
.
include
.
map
(
function
(
include
)
{
options
.
include
=
options
.
include
.
map
(
function
(
include
)
{
include
=
validateIncludedElement
.
call
(
this
,
include
,
options
.
daoFactory
)
include
=
validateIncludedElement
.
call
(
this
,
include
,
options
.
daoFactory
)
options
.
includeMap
[
include
.
as
]
=
include
options
.
includeNames
.
push
(
include
.
as
)
if
(
include
.
association
.
isMultiAssociation
)
options
.
hasMultiAssociation
=
true
if
(
include
.
association
.
isMultiAssociation
)
options
.
hasMultiAssociation
=
true
if
(
include
.
association
.
isSingleAssociation
)
options
.
hasSingleAssociation
=
true
if
(
include
.
association
.
isSingleAssociation
)
options
.
hasSingleAssociation
=
true
options
.
includeMap
[
include
.
as
]
=
include
options
.
hasIncludeWhere
=
options
.
hasIncludeWhere
||
include
.
hasIncludeWhere
||
!!
include
.
where
options
.
includeNames
.
push
(
include
.
as
)
options
.
hasIncludeRequired
=
options
.
hasIncludeRequired
||
include
.
hasIncludeRequired
||
!!
include
.
required
return
include
return
include
}.
bind
(
this
))
}.
bind
(
this
))
};
};
...
...
lib/dialects/abstract/query-generator.js
View file @
7df710b
...
@@ -461,14 +461,25 @@ module.exports = (function() {
...
@@ -461,14 +461,25 @@ module.exports = (function() {
- offset -> An offset value to start from. Only useable with limit!
- offset -> An offset value to start from. Only useable with limit!
*/
*/
selectQuery
:
function
(
tableName
,
options
,
factory
)
{
selectQuery
:
function
(
tableName
,
options
,
factory
)
{
var
table
=
null
var
table
=
null
,
self
=
this
,
self
=
this
,
joinQuery
=
""
,
query
,
limit
=
options
.
limit
options
=
options
||
{}
,
mainQueryItems
=
[]
options
.
table
=
table
=
Array
.
isArray
(
tableName
)
?
tableName
.
map
(
function
(
t
)
{
return
this
.
quoteIdentifiers
(
t
)
}.
bind
(
this
)).
join
(
", "
)
:
this
.
quoteIdentifiers
(
tableName
)
,
mainAttributes
=
options
.
attributes
,
mainJoinQueries
=
[]
// We'll use a subquery if there's a limit, if we have hasMany associations and if any of them are filtered
,
subQuery
=
limit
&&
options
&&
options
.
hasIncludeWhere
&&
options
.
hasMultiAssociation
,
subQueryItems
=
[]
,
subQueryAttributes
=
null
,
subJoinQueries
=
[]
options
=
options
||
{}
options
.
table
=
table
=
!
Array
.
isArray
(
tableName
)
?
this
.
quoteIdentifiers
(
tableName
)
:
tableName
.
map
(
function
(
t
)
{
return
this
.
quoteIdentifiers
(
t
)
}.
bind
(
this
)).
join
(
", "
)
options
.
attributes
=
options
.
attributes
&&
options
.
a
ttributes
.
map
(
function
(
attr
){
mainAttributes
=
mainAttributes
&&
mainA
ttributes
.
map
(
function
(
attr
){
var
addTable
=
true
var
addTable
=
true
if
(
attr
instanceof
Utils
.
fn
||
attr
instanceof
Utils
.
col
)
{
if
(
attr
instanceof
Utils
.
fn
||
attr
instanceof
Utils
.
col
)
{
...
@@ -490,12 +501,15 @@ module.exports = (function() {
...
@@ -490,12 +501,15 @@ module.exports = (function() {
}
}
return
attr
return
attr
}
.
bind
(
this
)).
join
(
", "
)
})
options
.
attributes
=
options
.
attributes
||
'*'
mainAttributes
=
mainAttributes
||
[
options
.
table
+
'.*'
]
if
(
options
.
include
)
{
if
(
subQuery
)
{
var
optAttributes
=
options
.
attributes
===
'*'
?
[
options
.
table
+
'.*'
]
:
[
options
.
attributes
]
subQueryAttributes
=
mainAttributes
mainAttributes
=
[
options
.
table
+
'.*'
]
}
if
(
options
.
include
)
{
var
generateJoinQuery
=
function
(
include
,
parentTable
)
{
var
generateJoinQuery
=
function
(
include
,
parentTable
)
{
var
table
=
include
.
daoFactory
.
tableName
var
table
=
include
.
daoFactory
.
tableName
,
as
=
include
.
as
,
as
=
include
.
as
...
@@ -524,7 +538,11 @@ module.exports = (function() {
...
@@ -524,7 +538,11 @@ module.exports = (function() {
return
self
.
quoteIdentifier
(
as
)
+
"."
+
self
.
quoteIdentifier
(
attr
)
+
" AS "
+
self
.
quoteIdentifier
(
as
+
"."
+
attr
)
return
self
.
quoteIdentifier
(
as
)
+
"."
+
self
.
quoteIdentifier
(
attr
)
+
" AS "
+
self
.
quoteIdentifier
(
as
+
"."
+
attr
)
})
})
optAttributes
=
optAttributes
.
concat
(
attributes
)
if
(
include
.
hasIncludeRequired
||
include
.
required
)
{
subQueryAttributes
=
subQueryAttributes
.
concat
(
attributes
)
}
else
{
mainAttributes
=
mainAttributes
.
concat
(
attributes
)
}
}
}
if
(
through
)
{
if
(
through
)
{
...
@@ -534,7 +552,13 @@ module.exports = (function() {
...
@@ -534,7 +552,13 @@ module.exports = (function() {
return
self
.
quoteIdentifier
(
throughAs
)
+
"."
+
self
.
quoteIdentifier
(
attr
)
+
" AS "
+
self
.
quoteIdentifier
(
throughAs
+
"."
+
attr
)
return
self
.
quoteIdentifier
(
throughAs
)
+
"."
+
self
.
quoteIdentifier
(
attr
)
+
" AS "
+
self
.
quoteIdentifier
(
throughAs
+
"."
+
attr
)
})
})
if
(
options
.
includeIgnoreAttributes
!==
false
)
optAttributes
=
optAttributes
.
concat
(
throughAttributes
)
if
(
options
.
includeIgnoreAttributes
!==
false
)
{
if
(
include
.
hasIncludeRequired
||
include
.
required
)
{
subQueryAttributes
=
subQueryAttributes
.
concat
(
attributes
)
}
else
{
mainAttributes
=
mainAttributes
.
concat
(
throughAttributes
)
}
}
var
primaryKeysSource
=
Object
.
keys
(
association
.
source
.
primaryKeys
)
var
primaryKeysSource
=
Object
.
keys
(
association
.
source
.
primaryKeys
)
,
tableSource
=
parentTable
,
tableSource
=
parentTable
...
@@ -584,46 +608,90 @@ module.exports = (function() {
...
@@ -584,46 +608,90 @@ module.exports = (function() {
}
}
options
.
include
.
forEach
(
function
(
include
)
{
options
.
include
.
forEach
(
function
(
include
)
{
joinQuery
+=
generateJoinQuery
(
include
,
tableName
)
var
joinQueryItem
=
generateJoinQuery
(
include
,
tableName
)
}.
bind
(
this
))
options
.
attributes
=
optAttributes
.
join
(
', '
)
if
(
include
.
hasIncludeWhere
||
include
.
where
)
{
subJoinQueries
.
push
(
joinQueryItem
)
}
else
{
mainJoinQueries
.
push
(
joinQueryItem
)
}
}.
bind
(
this
))
}
}
var
conditionalJoins
=
((
options
.
hasMultiAssociation
&&
(
options
.
limit
||
options
.
offset
))
||
!
options
.
include
)
&&
this
.
getConditionalJoins
(
options
,
factory
),
//var conditionalJoins = ((options.hasMultiAssociation && (options.limit || options.offset)) || !options.include) && this.getConditionalJoins(options, factory),
query
;
if
(
conditionalJoins
)
{
/*
if (conditionalJoins) {
query = "SELECT " + options.attributes + " FROM ( "
query = "SELECT " + options.attributes + " FROM ( "
+ "SELECT " + options.table + ".* FROM " + options.table + this.getConditionalJoins(options, factory)
+ "SELECT " + options.table + ".* FROM " + options.table + this.getConditionalJoins(options, factory)
} else {*/
//query += "SELECT " + mainAttributes.join(',') + " FROM " + options.table
//query += mainJoinQueries.concat(subJoinQueries).join('')
//}
if
(
subQuery
)
{
subQueryItems
.
push
(
"SELECT "
+
subQueryAttributes
.
join
(
','
)
+
" FROM "
+
options
.
table
)
subQueryItems
.
push
(
subJoinQueries
.
join
(
''
))
}
else
{
}
else
{
query
=
"SELECT "
+
options
.
attributes
+
" FROM "
+
options
.
table
mainQueryItems
.
push
(
"SELECT "
+
mainAttributes
.
join
(
','
)
+
" FROM "
+
options
.
table
)
query
+=
joinQuery
mainQueryItems
.
push
(
mainJoinQueries
.
join
(
''
))
}
}
if
(
options
.
hasOwnProperty
(
'where'
))
{
if
(
options
.
hasOwnProperty
(
'where'
))
{
options
.
where
=
this
.
getWhereConditions
(
options
.
where
,
tableName
,
factory
,
options
)
options
.
where
=
this
.
getWhereConditions
(
options
.
where
,
tableName
,
factory
,
options
)
query
+=
" WHERE "
+
options
.
where
if
(
subQuery
)
{
subQueryItems
.
push
(
" WHERE "
+
options
.
where
)
}
else
{
mainQueryItems
.
push
(
" WHERE "
+
options
.
where
)
}
}
}
if
(
options
.
group
)
{
if
(
options
.
group
)
{
options
.
group
=
Array
.
isArray
(
options
.
group
)
?
options
.
group
.
map
(
function
(
t
)
{
return
this
.
quote
(
t
)
}.
bind
(
this
)).
join
(
', '
)
:
options
.
group
options
.
group
=
Array
.
isArray
(
options
.
group
)
?
options
.
group
.
map
(
function
(
t
)
{
return
this
.
quote
(
t
)
}.
bind
(
this
)).
join
(
', '
)
:
options
.
group
query
+=
" GROUP BY "
+
options
.
group
if
(
subQuery
)
{
subQueryItems
.
push
(
" GROUP BY "
+
options
.
group
)
}
else
{
mainQueryItems
.
push
(
" GROUP BY "
+
options
.
group
)
}
}
}
if
(
options
.
order
)
{
if
(
options
.
order
)
{
options
.
order
=
Array
.
isArray
(
options
.
order
)
?
options
.
order
.
map
(
function
(
t
)
{
return
this
.
quote
(
t
)
}.
bind
(
this
)).
join
(
', '
)
:
options
.
order
options
.
order
=
Array
.
isArray
(
options
.
order
)
?
options
.
order
.
map
(
function
(
t
)
{
return
this
.
quote
(
t
)
}.
bind
(
this
)).
join
(
', '
)
:
options
.
order
query
+=
" ORDER BY "
+
options
.
order
if
(
subQuery
)
{
subQueryItems
.
push
(
" ORDER BY "
+
options
.
order
)
}
else
{
mainQueryItems
.
push
(
" ORDER BY "
+
options
.
order
)
}
}
}
query
=
this
.
addLimitAndOffset
(
options
,
query
)
if
(
conditionalJoins
)
{
var
limitOrder
=
this
.
addLimitAndOffset
(
options
,
query
)
if
(
limitOrder
)
{
if
(
subQuery
)
{
subQueryItems
.
push
(
limitOrder
)
}
else
{
mainQueryItems
.
push
(
limitOrder
)
}
}
//console.log(subQueryItems)
/*if (conditionalJoins) {
query += ") AS " + options.table
query += ") AS " + options.table
query += joinQuery
query += joinQuery
}*/
if
(
subQuery
)
{
//console.log(mainQueryItems)
//" + mainAttributes.join(',') + "
query
=
"SELECT "
+
mainAttributes
.
join
(
','
)
+
" FROM ("
query
+=
subQueryItems
.
join
(
''
)
query
+=
") AS "
+
options
.
table
query
+=
mainJoinQueries
.
join
(
''
)
}
else
{
query
=
mainQueryItems
.
join
(
''
)
}
}
query
+=
";"
//console.log(query)
return
query
return
query
},
},
...
@@ -673,6 +741,8 @@ module.exports = (function() {
...
@@ -673,6 +741,8 @@ module.exports = (function() {
},
},
addLimitAndOffset
:
function
(
options
,
query
){
addLimitAndOffset
:
function
(
options
,
query
){
query
=
query
||
""
if
(
options
.
offset
&&
!
options
.
limit
)
{
if
(
options
.
offset
&&
!
options
.
limit
)
{
query
+=
" LIMIT "
+
options
.
offset
+
", "
+
10000000000000
;
query
+=
" LIMIT "
+
options
.
offset
+
", "
+
10000000000000
;
}
else
if
(
options
.
limit
&&
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
}
else
if
(
options
.
limit
&&
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
...
...
lib/dialects/mysql/query-generator.js
View file @
7df710b
...
@@ -374,6 +374,7 @@ module.exports = (function() {
...
@@ -374,6 +374,7 @@ module.exports = (function() {
},
},
addLimitAndOffset
:
function
(
options
,
query
){
addLimitAndOffset
:
function
(
options
,
query
){
query
=
query
||
""
if
(
options
.
offset
&&
!
options
.
limit
)
{
if
(
options
.
offset
&&
!
options
.
limit
)
{
query
+=
" LIMIT "
+
options
.
offset
+
", "
+
18440000000000000000
;
query
+=
" LIMIT "
+
options
.
offset
+
", "
+
18440000000000000000
;
}
else
if
(
options
.
limit
&&
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
}
else
if
(
options
.
limit
&&
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
...
...
lib/dialects/postgres/query-generator.js
View file @
7df710b
...
@@ -389,6 +389,7 @@ module.exports = (function() {
...
@@ -389,6 +389,7 @@ module.exports = (function() {
},
},
addLimitAndOffset
:
function
(
options
,
query
){
addLimitAndOffset
:
function
(
options
,
query
){
query
=
query
||
""
if
(
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
if
(
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
if
(
options
.
limit
)
{
if
(
options
.
limit
)
{
query
+=
" LIMIT "
+
options
.
limit
query
+=
" LIMIT "
+
options
.
limit
...
...
lib/dialects/sqlite/query-generator.js
View file @
7df710b
...
@@ -132,6 +132,7 @@ module.exports = (function() {
...
@@ -132,6 +132,7 @@ module.exports = (function() {
},
},
addLimitAndOffset
:
function
(
options
,
query
){
addLimitAndOffset
:
function
(
options
,
query
){
query
=
query
||
""
if
(
options
.
offset
&&
!
options
.
limit
)
{
if
(
options
.
offset
&&
!
options
.
limit
)
{
query
+=
" LIMIT "
+
options
.
offset
+
", "
+
10000000000000
;
query
+=
" LIMIT "
+
options
.
offset
+
", "
+
10000000000000
;
}
else
if
(
options
.
limit
&&
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
}
else
if
(
options
.
limit
&&
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
...
...
test/associations/multiple-level-filters.test.js
View file @
7df710b
...
@@ -47,12 +47,12 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
...
@@ -47,12 +47,12 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
Task
.
findAll
({
Task
.
findAll
({
where
:
{
where
:
{
'project.user.username'
:
'leia'
'project.user.username'
:
'leia'
}
/*
,
},
include
:
[
include
:
[
{
model
:
Project
,
include
:
[
{
model
:
Project
,
include
:
[
User
User
]}
]}
]
*/
]
}).
done
(
function
(
err
,
tasks
){
}).
done
(
function
(
err
,
tasks
){
expect
(
err
).
not
.
to
.
be
.
ok
expect
(
err
).
not
.
to
.
be
.
ok
...
@@ -113,12 +113,12 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
...
@@ -113,12 +113,12 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
where
:
{
where
:
{
'project.user.username'
:
'leia'
,
'project.user.username'
:
'leia'
,
'project.user.id'
:
1
'project.user.id'
:
1
}
/*
,
},
include
:
[
include
:
[
{
model
:
Project
,
include
:
[
{
model
:
Project
,
include
:
[
User
User
]}
]}
]
*/
]
}).
success
(
function
(
tasks
){
}).
success
(
function
(
tasks
){
try
{
try
{
expect
(
tasks
.
length
).
to
.
be
.
equal
(
2
);
expect
(
tasks
.
length
).
to
.
be
.
equal
(
2
);
...
@@ -175,12 +175,12 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
...
@@ -175,12 +175,12 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
User
.
findAll
({
User
.
findAll
({
where
:
{
where
:
{
'projects.tasks.title'
:
'fight empire'
'projects.tasks.title'
:
'fight empire'
}
/*
,
},
include
:
[
include
:
[
{
model
:
Project
,
include
:
[
{
model
:
Project
,
include
:
[
Task
Task
]}
]}
]
*/
]
}).
done
(
function
(
err
,
users
){
}).
done
(
function
(
err
,
users
){
try
{
try
{
expect
(
users
.
length
).
to
.
be
.
equal
(
1
);
expect
(
users
.
length
).
to
.
be
.
equal
(
1
);
...
@@ -224,10 +224,10 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
...
@@ -224,10 +224,10 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
User
.
findAll
({
User
.
findAll
({
where
:
{
where
:
{
'projects.title'
:
'republic'
'projects.title'
:
'republic'
}
/*
,
},
include
:
[
include
:
[
{
model
:
Project
}
{
model
:
Project
}
]
*/
]
}).
success
(
function
(
users
){
}).
success
(
function
(
users
){
try
{
try
{
expect
(
users
.
length
).
to
.
be
.
equal
(
1
);
expect
(
users
.
length
).
to
.
be
.
equal
(
1
);
...
...
test/include.test.js
View file @
7df710b
...
@@ -514,836 +514,6 @@ describe(Support.getTestDialectTeaser("Include"), function () {
...
@@ -514,836 +514,6 @@ describe(Support.getTestDialectTeaser("Include"), function () {
})
})
})
})
describe
(
'findAll'
,
function
()
{
it
(
'should support an include with multiple different association types'
,
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
,
Rank
]},
{
model
:
Product
,
include
:
[
Tag
,
{
model
:
Tag
,
as
:
'Category'
},
Price
]}
],
order
:
'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
)
})
})
it
(
'should support many levels of belongsTo'
,
function
(
done
)
{
var
A
=
this
.
sequelize
.
define
(
'A'
,
{})
,
B
=
this
.
sequelize
.
define
(
'B'
,
{})
,
C
=
this
.
sequelize
.
define
(
'C'
,
{})
,
D
=
this
.
sequelize
.
define
(
'D'
,
{})
,
E
=
this
.
sequelize
.
define
(
'E'
,
{})
,
F
=
this
.
sequelize
.
define
(
'F'
,
{})
,
G
=
this
.
sequelize
.
define
(
'G'
,
{})
,
H
=
this
.
sequelize
.
define
(
'H'
,
{})
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
(
'User'
,
{})
,
Item
=
this
.
sequelize
.
define
(
'Item'
,
{
'test'
:
DataTypes
.
STRING
})
,
Order
=
this
.
sequelize
.
define
(
'Order'
,
{
'position'
:
DataTypes
.
INTEGER
})
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
})
,
Tag
=
this
.
sequelize
.
define
(
'Tag'
,
{
name
:
DataTypes
.
STRING
})
,
ProductTag
=
this
.
sequelize
.
define
(
'ProductTag'
,
{
priority
:
DataTypes
.
INTEGER
})
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'
,
{})
,
Group
=
this
.
sequelize
.
define
(
'Group'
,
{})
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'
,
{})
,
Group
=
this
.
sequelize
.
define
(
'Group'
,
{
name
:
DataTypes
.
STRING
})
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 hasOne include'
,
function
(
done
)
{
var
User
=
this
.
sequelize
.
define
(
'User'
,
{})
,
Project
=
this
.
sequelize
.
define
(
'Project'
,
{
title
:
DataTypes
.
STRING
})
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
})
,
Tag
=
this
.
sequelize
.
define
(
'Tag'
,
{
name
:
DataTypes
.
STRING
})
,
ProductTag
=
this
.
sequelize
.
define
(
'ProductTag'
,
{
priority
:
DataTypes
.
INTEGER
})
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'
,
{})
,
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
()
{
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'
,
{})
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment