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 91aef96d
authored
Jan 27, 2014
by
Overlook Motel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
order by nested associations
1 parent
5ae3cc26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
17 deletions
lib/dialects/abstract/query-generator.js
lib/utils.js
test/dao-factory/findAll.test.js
lib/dialects/abstract/query-generator.js
View file @
91aef96
...
...
@@ -331,7 +331,14 @@ module.exports = (function() {
/*
Quote an object based on its type. This is a more general version of quoteIdentifiers
Strings: should proxy to quoteIdentifiers
Arrays: First argument should be qouted, second argument should be append without quoting
Arrays:
* Expects array in the form: [<model> (optional), <model> (optional),... String, String (optional)]
Each <model> can be a daoFactory or an object {model: DaoFactory, as: String}, matching include
* Zero or more models can be included in the array and are used to trace a path through the tree of
included nested associations. This produces the correct table name for the ORDER BY/GROUP BY SQL
and quotes it.
* If a single string is appended to end of array, it is quoted.
If two strings appended, the 1st string is quoted, the 2nd string unquoted.
Objects:
* If raw is set, that value should be returned verbatim, without quoting
* If fn is set, the string should start with the value of fn, starting paren, followed by
...
...
@@ -339,14 +346,71 @@ module.exports = (function() {
unless they are themselves objects
* If direction is set, should be prepended
Currently this function is only used for ordering / grouping columns, but it could
Currently this function is only used for ordering / grouping columns
and Sequelize.col()
, but it could
potentially also be used for other places where we want to be able to call SQL functions (e.g. as default values)
*/
quote
:
function
(
obj
,
force
)
{
quote
:
function
(
obj
,
parent
,
force
)
{
if
(
Utils
.
_
.
isString
(
obj
))
{
return
this
.
quoteIdentifiers
(
obj
,
force
)
}
else
if
(
Array
.
isArray
(
obj
))
{
return
this
.
quote
(
obj
[
0
],
force
)
+
' '
+
obj
[
1
]
// loop through array, adding table names of models to quoted
// (checking associations to see if names should be singularised or not)
var
quoted
=
[]
,
i
,
len
=
obj
.
length
for
(
i
=
0
;
i
<
len
-
1
;
i
++
)
{
var
item
=
obj
[
i
]
if
(
Utils
.
_
.
isString
(
item
)
||
item
instanceof
Utils
.
fn
||
item
instanceof
Utils
.
col
||
item
instanceof
Utils
.
literal
||
item
instanceof
Utils
.
cast
||
'raw'
in
item
)
{
break
}
if
(
!
Utils
.
_
.
isPlainObject
(
item
))
{
item
=
{
model
:
item
}
}
// find applicable association for linking parent to this model
var
model
=
item
.
model
,
as
,
associations
=
parent
.
associations
,
association
if
(
item
.
hasOwnProperty
(
'as'
))
{
as
=
item
.
as
association
=
Utils
.
_
.
find
(
associations
,
function
(
association
,
associationName
)
{
return
association
.
target
===
model
&&
associationName
===
as
})
}
else
{
association
=
Utils
.
_
.
find
(
associations
,
function
(
association
,
associationName
)
{
return
association
.
target
===
model
?
associationName
===
(
association
.
doubleLinked
?
association
.
combinedName
:
(
association
.
isSingleAssociation
?
Utils
.
singularize
(
model
.
tableName
,
model
.
options
.
language
)
:
parent
.
tableName
+
model
.
tableName
)
)
:
association
.
targetAssociation
&&
association
.
targetAssociation
.
through
===
model
})
// NB association.target !== model clause below is to singularize names of through tables in hasMany-hasMany joins
as
=
(
association
&&
(
association
.
isSingleAssociation
||
association
.
target
!==
model
))
?
Utils
.
singularize
(
model
.
tableName
,
model
.
options
.
language
)
:
model
.
tableName
}
quoted
[
i
]
=
as
if
(
!
association
)
{
throw
new
Error
(
'\''
+
quoted
.
join
(
'.'
)
+
'\' in order / group clause is not valid association'
)
}
parent
=
model
}
// add 1st string as quoted, 2nd as unquoted raw
var
sql
=
(
i
>
0
?
this
.
quoteIdentifier
(
quoted
.
join
(
'.'
))
+
'.'
:
''
)
+
this
.
quote
(
obj
[
i
],
parent
,
force
)
if
(
i
<
len
-
1
)
{
sql
+=
' '
+
obj
[
i
+
1
]
}
return
sql
}
else
if
(
obj
instanceof
Utils
.
fn
||
obj
instanceof
Utils
.
col
||
obj
instanceof
Utils
.
literal
||
obj
instanceof
Utils
.
cast
)
{
return
obj
.
toString
(
this
)
}
else
if
(
Utils
.
_
.
isObject
(
obj
)
&&
'raw'
in
obj
)
{
...
...
@@ -497,12 +561,12 @@ module.exports = (function() {
}
if
(
attr
instanceof
Utils
.
fn
||
attr
instanceof
Utils
.
col
)
{
return
self
.
quote
(
attr
)
return
attr
.
toString
(
self
)
}
if
(
Array
.
isArray
(
attr
)
&&
attr
.
length
==
2
)
{
if
(
attr
[
0
]
instanceof
Utils
.
fn
||
attr
[
0
]
instanceof
Utils
.
col
)
{
attr
[
0
]
=
self
.
quote
(
attr
[
0
]
)
attr
[
0
]
=
attr
[
0
].
toString
(
self
)
addTable
=
false
}
attr
=
[
attr
[
0
],
this
.
quoteIdentifier
(
attr
[
1
])].
join
(
' as '
)
...
...
@@ -703,7 +767,7 @@ module.exports = (function() {
// Add GROUP BY to sub or main query
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
,
factory
)
}.
bind
(
this
)).
join
(
', '
)
:
options
.
group
if
(
subQuery
)
{
subQueryItems
.
push
(
" GROUP BY "
+
options
.
group
)
}
else
{
...
...
@@ -723,7 +787,7 @@ module.exports = (function() {
// Add ORDER to sub or main query
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
,
factory
)
}.
bind
(
this
)).
join
(
', '
)
:
options
.
order
if
(
subQuery
)
{
subQueryItems
.
push
(
" ORDER BY "
+
options
.
order
)
...
...
@@ -950,9 +1014,9 @@ module.exports = (function() {
})
if
(
options
.
include
)
{
return
this
.
quoteIdentifier
(
keyParts
.
join
(
'.'
))
+
'.'
+
this
.
quote
(
attributePart
);
return
this
.
quoteIdentifier
(
keyParts
.
join
(
'.'
))
+
'.'
+
this
.
quoteIdentifiers
(
attributePart
)
}
return
this
.
quoteIdentifiers
(
dao
.
tableName
+
'.'
+
attributePart
);
return
this
.
quoteIdentifiers
(
dao
.
tableName
+
'.'
+
attributePart
)
},
getConditionalJoins
:
function
(
options
,
originalDao
){
...
...
lib/utils.js
View file @
91aef96
...
...
@@ -534,6 +534,9 @@ var Utils = module.exports = {
},
col
:
function
(
col
)
{
if
(
arguments
.
length
>
1
)
{
col
=
Array
.
prototype
.
slice
.
call
(
arguments
);
}
this
.
col
=
col
},
...
...
@@ -588,23 +591,27 @@ Utils.cast.prototype.toString = function(queryGenerator) {
return
'CAST('
+
this
.
val
+
' AS '
+
this
.
type
.
toUpperCase
()
+
')'
}
Utils
.
fn
.
prototype
.
toString
=
function
(
queryGenerator
)
{
Utils
.
fn
.
prototype
.
toString
=
function
(
queryGenerator
,
parentModel
)
{
return
this
.
fn
+
'('
+
this
.
args
.
map
(
function
(
arg
)
{
if
(
arg
instanceof
Utils
.
fn
||
arg
instanceof
Utils
.
col
)
{
return
arg
.
toString
(
queryGenerator
)
return
arg
.
toString
(
queryGenerator
,
parentModel
)
}
else
{
return
queryGenerator
.
escape
(
arg
)
}
}).
join
(
', '
)
+
')'
}
Utils
.
col
.
prototype
.
toString
=
function
(
queryGenerator
)
{
if
(
this
.
col
.
indexOf
(
'*'
)
===
0
)
{
Utils
.
col
.
prototype
.
toString
=
function
(
queryGenerator
,
parentModel
)
{
if
(
Array
.
isArray
(
this
.
col
))
{
if
(
!
parent
)
{
throw
new
Error
(
'Cannot call Sequelize.col() with array outside of order / group clause'
)
}
}
else
if
(
this
.
col
.
indexOf
(
'*'
)
===
0
)
{
return
'*'
}
return
queryGenerator
.
quote
(
this
.
col
)
return
queryGenerator
.
quote
(
this
.
col
,
parentModel
)
}
Utils
.
CustomEventEmitter
=
require
(
__dirname
+
"/emitters/custom-event-emitter"
)
Utils
.
QueryChainer
=
require
(
__dirname
+
"/query-chainer"
)
Utils
.
Lingo
=
require
(
"lingo"
)
\ No newline at end of file
Utils
.
Lingo
=
require
(
"lingo"
)
test/dao-factory/findAll.test.js
View file @
91aef96
This diff is collapsed.
Click to expand it.
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