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 60bd58c4
authored
Feb 23, 2014
by
Mick Hansen
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1421 from overlookmotel/include-all
Eager loading all associations
2 parents
97f840e3
38e48b5c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
248 additions
and
24 deletions
lib/dao-factory.js
test/dao-factory/findAll.test.js
lib/dao-factory.js
View file @
60bd58c
...
@@ -1345,8 +1345,38 @@ module.exports = (function() {
...
@@ -1345,8 +1345,38 @@ module.exports = (function() {
options
.
includeMap
=
{}
options
.
includeMap
=
{}
options
.
hasSingleAssociation
=
false
options
.
hasSingleAssociation
=
false
options
.
hasMultiAssociation
=
false
options
.
hasMultiAssociation
=
false
options
.
include
=
options
.
include
.
map
(
function
(
include
)
{
include
=
validateIncludedElement
.
call
(
this
,
include
,
options
.
daoFactory
,
tableNames
)
// if include is not an array, wrap in an array
if
(
!
Array
.
isArray
(
options
.
include
))
{
options
.
include
=
[
options
.
include
]
}
// convert all included elements to { daoFactory: Model } form
var
includes
=
options
.
include
=
options
.
include
.
map
(
function
(
include
)
{
if
(
include
instanceof
DAOFactory
)
{
return
{
daoFactory
:
include
}
}
else
if
(
typeof
include
!==
'object'
)
{
throw
new
Error
(
'Include unexpected. Element has to be either an instance of DAOFactory or an object.'
)
}
else
if
(
include
.
hasOwnProperty
(
'model'
))
{
include
.
daoFactory
=
include
.
model
delete
include
.
model
}
return
include
})
// validate all included elements
for
(
var
index
=
0
;
index
<
includes
.
length
;
index
++
)
{
var
include
=
includes
[
index
]
if
(
include
.
all
)
{
includes
.
splice
(
index
,
1
)
index
--
validateIncludedAllElement
.
call
(
this
,
includes
,
include
)
continue
}
include
=
includes
[
index
]
=
validateIncludedElement
.
call
(
this
,
include
,
tableNames
)
options
.
includeMap
[
include
.
as
]
=
include
options
.
includeMap
[
include
.
as
]
=
include
options
.
includeNames
.
push
(
include
.
as
)
options
.
includeNames
.
push
(
include
.
as
)
...
@@ -1357,28 +1387,11 @@ module.exports = (function() {
...
@@ -1357,28 +1387,11 @@ module.exports = (function() {
options
.
hasIncludeWhere
=
options
.
hasIncludeWhere
||
include
.
hasIncludeWhere
||
!!
include
.
where
options
.
hasIncludeWhere
=
options
.
hasIncludeWhere
||
include
.
hasIncludeWhere
||
!!
include
.
where
options
.
hasIncludeRequired
=
options
.
hasIncludeRequired
||
include
.
hasIncludeRequired
||
!!
include
.
required
options
.
hasIncludeRequired
=
options
.
hasIncludeRequired
||
include
.
hasIncludeRequired
||
!!
include
.
required
return
include
}.
bind
(
this
))
};
var
validateIncludedElement
=
function
(
include
,
parent
,
tableNames
)
{
if
(
include
instanceof
DAOFactory
)
{
include
=
{
daoFactory
:
include
}
}
if
(
typeof
parent
===
"undefined"
)
{
parent
=
this
}
if
(
typeof
include
!==
'object'
)
{
throw
new
Error
(
'Include unexpected. Element has to be either an instance of DAOFactory or an object.'
)
}
}
}
if
(
include
.
hasOwnProperty
(
'model'
))
{
var
validateIncludedElement
=
function
(
include
,
tableNames
)
{
include
.
daoFactory
=
include
.
model
if
(
!
include
.
hasOwnProperty
(
'daoFactory'
))
{
delete
include
.
model
}
else
if
(
!
include
.
hasOwnProperty
(
'daoFactory'
))
{
throw
new
Error
(
'Include malformed. Expected attributes: daoFactory, as!'
)
throw
new
Error
(
'Include malformed. Expected attributes: daoFactory, as!'
)
}
}
...
@@ -1403,7 +1416,7 @@ module.exports = (function() {
...
@@ -1403,7 +1416,7 @@ module.exports = (function() {
if
(
include
.
_pseudo
)
return
include
if
(
include
.
_pseudo
)
return
include
// check if the current daoFactory is actually associated with the passed daoFactory - or it's a pseudo include
// check if the current daoFactory is actually associated with the passed daoFactory - or it's a pseudo include
var
association
=
parent
.
getAssociation
(
include
.
daoFactory
,
include
.
as
)
var
association
=
this
.
getAssociation
(
include
.
daoFactory
,
include
.
as
)
if
(
association
)
{
if
(
association
)
{
include
.
association
=
association
include
.
association
=
association
include
.
as
=
association
.
as
include
.
as
=
association
.
as
...
@@ -1432,7 +1445,7 @@ module.exports = (function() {
...
@@ -1432,7 +1445,7 @@ module.exports = (function() {
// Validate child includes
// Validate child includes
if
(
include
.
hasOwnProperty
(
'include'
))
{
if
(
include
.
hasOwnProperty
(
'include'
))
{
validateIncludedElements
(
include
,
tableNames
)
validateIncludedElements
.
call
(
include
.
daoFactory
,
include
,
tableNames
)
}
}
return
include
return
include
...
@@ -1449,6 +1462,100 @@ module.exports = (function() {
...
@@ -1449,6 +1462,100 @@ module.exports = (function() {
}
}
}
}
var
validateIncludedAllElement
=
function
(
includes
,
include
)
{
// check 'all' attribute provided is valid
var
all
=
include
.
all
delete
include
.
all
if
(
all
!==
true
)
{
if
(
!
Array
.
isArray
(
all
))
{
all
=
[
all
]
}
var
validTypes
=
{
BelongsTo
:
true
,
HasOne
:
true
,
HasMany
:
true
,
One
:
[
'BelongsTo'
,
'HasOne'
],
Has
:
[
'HasOne'
,
'HasMany'
],
Many
:
[
'HasMany'
]
}
for
(
var
i
=
0
;
i
<
all
.
length
;
i
++
)
{
var
type
=
all
[
i
]
if
(
type
==
'All'
)
{
all
=
true
break
}
var
types
=
validTypes
[
type
]
if
(
!
types
)
{
throw
new
Error
(
'include all \''
+
type
+
'\' is not valid - must be BelongsTo, HasOne, HasMany, One, Has, Many or All'
)
}
if
(
types
!==
true
)
{
// replace type placeholder e.g. 'One' with it's constituent types e.g. 'HasOne', 'BelongsTo'
all
.
splice
(
i
,
1
)
i
--
for
(
var
j
=
0
;
j
<
types
.
length
;
j
++
)
{
if
(
all
.
indexOf
(
types
[
j
])
==
-
1
)
{
all
.
unshift
(
types
[
j
])
i
++
}
}
}
}
}
// add all associations of types specified to includes
var
nested
=
include
.
nested
if
(
nested
)
{
delete
include
.
nested
if
(
!
include
.
include
)
{
include
.
include
=
[]
}
else
if
(
!
Array
.
isArray
(
include
.
include
))
{
include
.
include
=
[
include
.
include
]
}
}
var
used
=
[]
;(
function
addAllIncludes
(
parent
,
includes
)
{
used
.
push
(
parent
)
Utils
.
_
.
forEach
(
parent
.
associations
,
function
(
association
)
{
if
(
all
!==
true
&&
all
.
indexOf
(
association
.
associationType
)
==
-
1
)
{
return
}
// check if model already included, and skip if so
var
model
=
association
.
target
var
as
=
association
.
options
.
as
if
(
Utils
.
_
.
find
(
includes
,
{
daoFactory
:
model
,
as
:
as
}))
{
return
}
// skip if recursing over a model already nested
if
(
nested
&&
used
.
indexOf
(
model
)
!=
-
1
)
{
return
}
// include this model
var
thisInclude
=
optClone
(
include
)
thisInclude
.
daoFactory
=
model
if
(
as
)
{
thisInclude
.
as
=
as
}
includes
.
push
(
thisInclude
)
// run recursively if nested
if
(
nested
)
{
addAllIncludes
(
model
,
thisInclude
.
include
)
}
})
used
.
pop
()
})(
this
,
includes
)
}
var
replaceReferencesWithTableNames
=
function
(
attributes
)
{
var
replaceReferencesWithTableNames
=
function
(
attributes
)
{
Object
.
keys
(
attributes
).
forEach
(
function
(
attrName
)
{
Object
.
keys
(
attributes
).
forEach
(
function
(
attrName
)
{
if
(
attributes
[
attrName
].
references
instanceof
DAOFactory
)
{
if
(
attributes
[
attrName
].
references
instanceof
DAOFactory
)
{
...
...
test/dao-factory/findAll.test.js
View file @
60bd58c
...
@@ -830,6 +830,123 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
...
@@ -830,6 +830,123 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
})
})
describe
(
'include all'
,
function
()
{
beforeEach
(
function
(
done
)
{
var
self
=
this
self
.
Continent
=
this
.
sequelize
.
define
(
'Continent'
,
{
name
:
Sequelize
.
STRING
})
self
.
Country
=
this
.
sequelize
.
define
(
'Country'
,
{
name
:
Sequelize
.
STRING
})
self
.
Industry
=
this
.
sequelize
.
define
(
'Industry'
,
{
name
:
Sequelize
.
STRING
})
self
.
Person
=
this
.
sequelize
.
define
(
'Person'
,
{
name
:
Sequelize
.
STRING
,
lastName
:
Sequelize
.
STRING
})
self
.
Continent
.
hasMany
(
self
.
Country
)
self
.
Country
.
belongsTo
(
self
.
Continent
)
self
.
Country
.
hasMany
(
self
.
Industry
)
self
.
Industry
.
hasMany
(
self
.
Country
)
self
.
Country
.
hasMany
(
self
.
Person
)
self
.
Person
.
belongsTo
(
self
.
Country
)
self
.
Country
.
hasMany
(
self
.
Person
,
{
as
:
'Residents'
,
foreignKey
:
'CountryResidentId'
})
self
.
Person
.
belongsTo
(
self
.
Country
,
{
as
:
'CountryResident'
,
foreignKey
:
'CountryResidentId'
})
async
.
forEach
([
self
.
Continent
,
self
.
Country
,
self
.
Industry
,
self
.
Person
],
function
(
model
,
callback
)
{
model
.
sync
({
force
:
true
}).
done
(
callback
)
},
function
()
{
async
.
parallel
({
europe
:
function
(
callback
)
{
self
.
Continent
.
create
({
name
:
'Europe'
}).
done
(
callback
)},
england
:
function
(
callback
)
{
self
.
Country
.
create
({
name
:
'England'
}).
done
(
callback
)},
coal
:
function
(
callback
)
{
self
.
Industry
.
create
({
name
:
'Coal'
}).
done
(
callback
)},
bob
:
function
(
callback
)
{
self
.
Person
.
create
({
name
:
'Bob'
,
lastName
:
'Becket'
}).
done
(
callback
)}
},
function
(
err
,
r
)
{
if
(
err
)
throw
err
_
.
forEach
(
r
,
function
(
item
,
itemName
)
{
self
[
itemName
]
=
item
})
async
.
parallel
([
function
(
callback
)
{
self
.
england
.
setContinent
(
self
.
europe
).
done
(
callback
)},
function
(
callback
)
{
self
.
england
.
addIndustry
(
self
.
coal
).
done
(
callback
)},
function
(
callback
)
{
self
.
bob
.
setCountry
(
self
.
england
).
done
(
callback
)},
function
(
callback
)
{
self
.
bob
.
setCountryResident
(
self
.
england
).
done
(
callback
)}
],
function
(
err
)
{
if
(
err
)
throw
err
done
()
})
})
})
})
it
(
'includes all associations'
,
function
(
done
)
{
this
.
Country
.
findAll
({
include
:
[
{
all
:
true
}
]
}).
done
(
function
(
err
,
countries
)
{
expect
(
err
).
not
.
to
.
be
.
ok
expect
(
countries
).
to
.
exist
expect
(
countries
[
0
]).
to
.
exist
expect
(
countries
[
0
].
continent
).
to
.
exist
expect
(
countries
[
0
].
industries
).
to
.
exist
expect
(
countries
[
0
].
persons
).
to
.
exist
expect
(
countries
[
0
].
residents
).
to
.
exist
done
()
})
})
it
(
'includes specific type of association'
,
function
(
done
)
{
this
.
Country
.
findAll
({
include
:
[
{
all
:
'BelongsTo'
}
]
}).
done
(
function
(
err
,
countries
)
{
expect
(
err
).
not
.
to
.
be
.
ok
expect
(
countries
).
to
.
exist
expect
(
countries
[
0
]).
to
.
exist
expect
(
countries
[
0
].
continent
).
to
.
exist
expect
(
countries
[
0
].
industries
).
not
.
to
.
exist
expect
(
countries
[
0
].
persons
).
not
.
to
.
exist
expect
(
countries
[
0
].
residents
).
not
.
to
.
exist
done
()
})
})
it
(
'utilises specified attributes'
,
function
(
done
)
{
this
.
Country
.
findAll
({
include
:
[
{
all
:
'HasMany'
,
attributes
:
[
'name'
]
}
]
}).
done
(
function
(
err
,
countries
)
{
expect
(
err
).
not
.
to
.
be
.
ok
expect
(
countries
).
to
.
exist
expect
(
countries
[
0
]).
to
.
exist
expect
(
countries
[
0
].
industries
).
to
.
exist
expect
(
countries
[
0
].
persons
).
to
.
exist
expect
(
countries
[
0
].
persons
[
0
]).
to
.
exist
expect
(
countries
[
0
].
persons
[
0
].
name
).
not
.
to
.
be
.
undefined
expect
(
countries
[
0
].
persons
[
0
].
lastName
).
to
.
be
.
undefined
expect
(
countries
[
0
].
residents
).
to
.
exist
expect
(
countries
[
0
].
residents
[
0
]).
to
.
exist
expect
(
countries
[
0
].
residents
[
0
].
name
).
not
.
to
.
be
.
undefined
expect
(
countries
[
0
].
residents
[
0
].
lastName
).
to
.
be
.
undefined
done
()
})
})
it
(
'is over-ruled by specified include'
,
function
(
done
)
{
this
.
Country
.
findAll
({
include
:
[
{
all
:
true
},
{
model
:
this
.
Continent
,
attributes
:
[]
}
]
}).
done
(
function
(
err
,
countries
)
{
expect
(
err
).
not
.
to
.
be
.
ok
expect
(
countries
).
to
.
exist
expect
(
countries
[
0
]).
to
.
exist
expect
(
countries
[
0
].
continent
).
to
.
exist
expect
(
countries
[
0
].
continent
.
name
).
to
.
be
.
undefined
done
()
})
})
it
(
'includes all nested associations'
,
function
(
done
)
{
this
.
Continent
.
findAll
({
include
:
[
{
all
:
true
,
nested
:
true
}
]
}).
done
(
function
(
err
,
continents
)
{
expect
(
err
).
not
.
to
.
be
.
ok
expect
(
continents
).
to
.
exist
expect
(
continents
[
0
]).
to
.
exist
expect
(
continents
[
0
].
countries
).
to
.
exist
expect
(
continents
[
0
].
countries
[
0
]).
to
.
exist
expect
(
continents
[
0
].
countries
[
0
].
industries
).
to
.
exist
expect
(
continents
[
0
].
countries
[
0
].
persons
).
to
.
exist
expect
(
continents
[
0
].
countries
[
0
].
residents
).
to
.
exist
expect
(
continents
[
0
].
countries
[
0
].
continent
).
not
.
to
.
exist
done
()
})
})
})
})
})
describe
(
'order by eager loaded tables'
,
function
()
{
describe
(
'order by eager loaded tables'
,
function
()
{
...
...
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