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 916a803f
authored
Oct 15, 2013
by
Rafael Martins
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Filter through relations working on postgres
1 parent
ea8dba06
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
237 deletions
lib/dialects/abstract/query-generator.js
lib/dialects/postgres/query-generator.js
test/associations/multiple-level-filters.test.js
lib/dialects/abstract/query-generator.js
View file @
916a803
...
...
@@ -365,12 +365,12 @@ module.exports = (function() {
joinQuery
=
""
options
=
options
||
{}
options
.
table
=
table
=
Array
.
isArray
(
tableName
)
?
tableName
.
map
(
function
(
t
)
{
return
this
.
quoteIdentifier
(
t
)}.
bind
(
this
)).
join
(
", "
)
:
this
.
quoteIdentifier
(
tableName
)
options
.
table
=
table
=
Array
.
isArray
(
tableName
)
?
tableName
.
map
(
function
(
t
)
{
return
this
.
quoteIdentifier
s
(
t
)
}.
bind
(
this
)).
join
(
", "
)
:
this
.
quoteIdentifiers
(
tableName
)
options
.
attributes
=
options
.
attributes
&&
options
.
attributes
.
map
(
function
(
attr
){
if
(
Array
.
isArray
(
attr
)
&&
attr
.
length
==
2
)
{
return
[
attr
[
0
],
this
.
quoteIdentifier
(
attr
[
1
])].
join
(
' as '
)
}
else
{
return
attr
.
indexOf
(
Utils
.
TICK_CHAR
)
<
0
?
this
.
quoteIdentifiers
(
attr
)
:
attr
return
attr
.
indexOf
(
Utils
.
TICK_CHAR
)
<
0
&&
attr
.
indexOf
(
'"'
)
<
0
?
this
.
quoteIdentifiers
(
attr
)
:
attr
}
}.
bind
(
this
)).
join
(
", "
)
options
.
attributes
=
options
.
attributes
||
'*'
...
...
@@ -615,6 +615,14 @@ module.exports = (function() {
return
joins
;
},
arrayValue
:
function
(
value
,
key
,
_key
){
var
_value
=
null
;
if
(
value
.
length
===
0
)
{
value
=
[
null
]
}
_value
=
"("
+
value
.
map
(
function
(
v
)
{
return
this
.
escape
(
v
)
}.
bind
(
this
)).
join
(
','
)
+
")"
return
[
_key
,
_value
].
join
(
" IN "
)
},
/*
Takes a hash and transforms it into a mysql where condition: {key: value, key2: value2} ==> key=value AND key2=value2
The values are transformed by the relevant datatype.
...
...
@@ -634,11 +642,7 @@ module.exports = (function() {
,
_value
=
null
if
(
Array
.
isArray
(
value
))
{
// is value an array?
if
(
value
.
length
===
0
)
{
value
=
[
null
]
}
_value
=
"("
+
value
.
map
(
function
(
v
)
{
return
this
.
escape
(
v
)
}.
bind
(
this
)).
join
(
','
)
+
")"
result
.
push
([
_key
,
_value
].
join
(
" IN "
))
result
.
push
(
this
.
arrayValue
(
value
,
key
,
_key
,
dao
))
}
else
if
((
value
)
&&
(
typeof
value
==
'object'
)
&&
!
(
value
instanceof
Date
))
{
if
(
!!
value
.
join
)
{
//using as sentinel for join column => value
...
...
lib/dialects/postgres/query-generator.js
View file @
916a803
...
...
@@ -144,6 +144,27 @@ module.exports = (function() {
attributes
:
attrString
.
join
(
', '
)
})
},
arrayValue
:
function
(
value
,
key
,
_key
,
factory
){
if
(
value
.
length
===
0
)
{
value
=
[
null
]
}
var
col
=
null
,
coltype
=
null
// Special conditions for searching within an array column type
var
_realKey
=
key
.
split
(
'.'
).
pop
()
if
(
!!
factory
&&
!!
factory
.
rawAttributes
[
_realKey
])
{
col
=
factory
.
rawAttributes
[
_realKey
]
coltype
=
col
.
type
if
(
coltype
&&
!
(
typeof
coltype
==
'string'
))
{
coltype
=
coltype
.
toString
();
}
}
if
(
col
&&
((
!!
coltype
&&
coltype
.
match
(
/
\[\]
$/
)
!==
null
)
||
(
col
.
toString
().
match
(
/
\[\]
$/
)
!==
null
)))
{
_value
=
'ARRAY['
+
value
.
map
(
this
.
escape
).
join
(
','
)
+
']::'
+
(
!!
col
.
type
?
col
.
type
:
col
.
toString
())
return
[
_key
,
_value
].
join
(
" && "
)
}
else
{
_value
=
"("
+
value
.
map
(
this
.
escape
).
join
(
','
)
+
")"
return
[
_key
,
_value
].
join
(
" IN "
)
}
},
removeColumnQuery
:
function
(
tableName
,
attributeName
)
{
var
query
=
"ALTER TABLE <%= tableName %> DROP COLUMN <%= attributeName %>;"
return
Utils
.
_
.
template
(
query
)({
...
...
@@ -230,100 +251,6 @@ module.exports = (function() {
})
},
selectQuery
:
function
(
tableName
,
options
,
factory
)
{
var
query
=
"SELECT <%= attributes %> FROM <%= table %>"
,
table
=
null
options
=
options
||
{}
options
.
table
=
table
=
Array
.
isArray
(
tableName
)
?
tableName
.
map
(
function
(
t
)
{
return
this
.
quoteIdentifiers
(
t
)
}.
bind
(
this
)).
join
(
", "
)
:
this
.
quoteIdentifiers
(
tableName
)
options
.
attributes
=
options
.
attributes
&&
options
.
attributes
.
map
(
function
(
attr
)
{
if
(
Array
.
isArray
(
attr
)
&&
attr
.
length
===
2
)
{
return
[
attr
[
0
],
this
.
quoteIdentifier
(
attr
[
1
])].
join
(
' as '
)
}
else
{
return
attr
.
indexOf
(
'"'
)
<
0
?
this
.
quoteIdentifiers
(
attr
)
:
attr
}
}.
bind
(
this
)).
join
(
", "
)
options
.
attributes
=
options
.
attributes
||
'*'
if
(
options
.
include
)
{
var
optAttributes
=
options
.
attributes
===
'*'
?
[
options
.
table
+
'.*'
]
:
[
options
.
attributes
]
options
.
include
.
forEach
(
function
(
include
)
{
var
attributes
=
include
.
attributes
.
map
(
function
(
attr
)
{
return
this
.
quoteIdentifier
(
include
.
as
)
+
"."
+
this
.
quoteIdentifier
(
attr
)
+
" AS "
+
this
.
quoteIdentifier
(
include
.
as
+
"."
+
attr
,
true
)
}.
bind
(
this
))
optAttributes
=
optAttributes
.
concat
(
attributes
)
var
joinQuery
=
' LEFT OUTER JOIN <%= table %> AS <%= as %> ON <%= tableLeft %>.<%= attrLeft %> = <%= tableRight %>.<%= attrRight %>'
if
(
!
include
.
association
.
connectorDAO
)
{
var
primaryKeysLeft
=
((
include
.
association
.
associationType
===
'BelongsTo'
)
?
Object
.
keys
(
include
.
association
.
target
.
primaryKeys
)
:
Object
.
keys
(
include
.
association
.
source
.
primaryKeys
))
query
+=
Utils
.
_
.
template
(
joinQuery
)({
table
:
this
.
quoteIdentifiers
(
include
.
daoFactory
.
tableName
),
as
:
this
.
quoteIdentifier
(
include
.
as
),
tableLeft
:
this
.
quoteIdentifier
((
include
.
association
.
associationType
===
'BelongsTo'
)
?
include
.
as
:
tableName
),
attrLeft
:
this
.
quoteIdentifier
(((
primaryKeysLeft
.
length
!==
1
)
?
'id'
:
primaryKeysLeft
[
0
])),
tableRight
:
this
.
quoteIdentifiers
((
include
.
association
.
associationType
===
'BelongsTo'
)
?
tableName
:
include
.
as
),
attrRight
:
this
.
quoteIdentifier
(
include
.
association
.
identifier
)
})
}
else
{
var
primaryKeysSource
=
Object
.
keys
(
include
.
association
.
source
.
primaryKeys
)
,
primaryKeysTarget
=
Object
.
keys
(
include
.
association
.
target
.
primaryKeys
)
query
+=
Utils
.
_
.
template
(
joinQuery
)({
table
:
this
.
quoteIdentifiers
(
include
.
association
.
connectorDAO
.
tableName
),
as
:
this
.
quoteIdentifier
(
include
.
association
.
connectorDAO
.
tableName
),
tableLeft
:
this
.
quoteIdentifiers
(
tableName
),
attrLeft
:
this
.
quoteIdentifier
(((
!
include
.
association
.
source
.
hasPrimaryKeys
||
primaryKeysSource
.
length
!==
1
)
?
'id'
:
primaryKeysSource
[
0
])),
tableRight
:
this
.
quoteIdentifiers
(
include
.
association
.
connectorDAO
.
tableName
),
attrRight
:
this
.
quoteIdentifier
(
include
.
association
.
identifier
)
})
query
+=
Utils
.
_
.
template
(
joinQuery
)({
table
:
this
.
quoteIdentifiers
(
include
.
daoFactory
.
tableName
),
as
:
this
.
quoteIdentifier
(
include
.
as
),
tableLeft
:
this
.
quoteIdentifiers
(
include
.
as
),
attrLeft
:
this
.
quoteIdentifier
(((
!
include
.
association
.
target
.
hasPrimaryKeys
||
primaryKeysTarget
.
length
!==
1
)
?
'id'
:
primaryKeysTarget
[
0
])),
tableRight
:
this
.
quoteIdentifiers
(
include
.
association
.
connectorDAO
.
tableName
),
attrRight
:
this
.
quoteIdentifier
(
include
.
association
.
foreignIdentifier
)
})
}
}.
bind
(
this
))
options
.
attributes
=
optAttributes
.
join
(
', '
)
}
if
(
options
.
hasOwnProperty
(
'where'
))
{
options
.
where
=
this
.
getWhereConditions
(
options
.
where
,
tableName
,
factory
)
query
+=
" WHERE <%= where %>"
}
if
(
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 <%= group %>"
}
if
(
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 <%= order %>"
}
if
(
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
if
(
options
.
limit
)
{
query
+=
" LIMIT <%= limit %>"
}
if
(
options
.
offset
)
{
query
+=
" OFFSET <%= offset %>"
}
}
query
+=
";"
return
Utils
.
_
.
template
(
query
)(
options
)
},
insertQuery
:
function
(
tableName
,
attrValueHash
,
attributes
)
{
attrValueHash
=
Utils
.
removeNullValuesFromHash
(
attrValueHash
,
this
.
options
.
omitNull
)
...
...
@@ -522,96 +449,18 @@ module.exports = (function() {
})
},
getWhereConditions
:
function
(
smth
,
tableName
,
factory
)
{
var
result
=
null
,
where
=
{}
if
(
Utils
.
isHash
(
smth
))
{
smth
=
Utils
.
prependTableNameToHash
(
tableName
,
smth
)
result
=
this
.
hashToWhereConditions
(
smth
,
factory
)
}
else
if
(
typeof
smth
===
'number'
)
{
var
primaryKeys
=
!!
factory
?
Object
.
keys
(
factory
.
primaryKeys
)
:
[]
if
(
primaryKeys
.
length
>
0
)
{
// Since we're just a number, assume only the first key
primaryKeys
=
primaryKeys
[
0
]
}
else
{
primaryKeys
=
'id'
addLimitAndOffset
:
function
(
options
,
query
){
if
(
!
(
options
.
include
&&
(
options
.
limit
===
1
)))
{
if
(
options
.
limit
)
{
query
+=
" LIMIT "
+
options
.
limit
}
where
[
primaryKeys
]
=
smth
smth
=
Utils
.
prependTableNameToHash
(
tableName
,
where
)
result
=
this
.
hashToWhereConditions
(
smth
)
}
else
if
(
typeof
smth
===
"string"
)
{
result
=
smth
}
else
if
(
Array
.
isArray
(
smth
))
{
result
=
Utils
.
format
(
smth
,
"postgres"
)
}
return
result
},
hashToWhereConditions
:
function
(
hash
,
factory
)
{
var
result
=
[]
for
(
var
key
in
hash
)
{
var
value
=
hash
[
key
]
//handle qualified key names
var
_key
=
this
.
quoteIdentifiers
(
key
)
,
_value
=
null
if
(
Array
.
isArray
(
value
))
{
if
(
value
.
length
===
0
)
{
value
=
[
null
]
}
var
col
=
null
,
coltype
=
null
// Special conditions for searching within an array column type
var
_realKey
=
key
.
split
(
'.'
).
pop
()
if
(
!!
factory
&&
!!
factory
.
rawAttributes
[
_realKey
])
{
col
=
factory
.
rawAttributes
[
_realKey
]
coltype
=
col
.
type
if
(
coltype
&&
!
(
typeof
coltype
==
'string'
))
{
coltype
=
coltype
.
toString
();
}
}
if
(
col
&&
((
!!
coltype
&&
coltype
.
match
(
/
\[\]
$/
)
!==
null
)
||
(
col
.
toString
().
match
(
/
\[\]
$/
)
!==
null
)))
{
_value
=
'ARRAY['
+
value
.
map
(
this
.
escape
).
join
(
','
)
+
']::'
+
(
!!
col
.
type
?
col
.
type
:
col
.
toString
())
result
.
push
([
_key
,
_value
].
join
(
" && "
))
}
else
{
_value
=
"("
+
value
.
map
(
this
.
escape
).
join
(
','
)
+
")"
result
.
push
([
_key
,
_value
].
join
(
" IN "
))
}
}
else
if
((
value
)
&&
(
typeof
value
===
"object"
))
{
if
(
!!
value
.
join
)
{
//using as sentinel for join column => value
_value
=
this
.
quoteIdentifiers
(
value
.
join
)
result
.
push
([
_key
,
_value
].
join
(
"="
))
}
else
{
for
(
var
logic
in
value
)
{
var
logicResult
=
Utils
.
getWhereLogic
(
logic
)
if
(
logic
===
"IN"
||
logic
===
"NOT IN"
)
{
var
values
=
Array
.
isArray
(
where
[
i
][
ii
])
?
where
[
i
][
ii
]
:
[
where
[
i
][
ii
]]
_where
[
_where
.
length
]
=
i
+
' '
+
logic
+
' ('
+
values
.
map
(
function
(){
return
'?'
}).
join
(
','
)
+
')'
_whereArgs
=
_whereArgs
.
concat
(
values
)
}
else
if
(
logicResult
===
"BETWEEN"
||
logicResult
===
"NOT BETWEEN"
)
{
_value
=
this
.
escape
(
value
[
logic
][
0
])
var
_value2
=
this
.
escape
(
value
[
logic
][
1
])
result
.
push
(
' ('
+
_key
+
' '
+
logicResult
+
' '
+
_value
+
' AND '
+
_value2
+
') '
)
}
else
{
_value
=
this
.
escape
(
value
[
logic
])
result
.
push
([
_key
,
_value
].
join
(
' '
+
logicResult
+
' '
))
}
}
}
}
else
{
_value
=
this
.
escape
(
value
)
result
.
push
((
_value
==
'NULL'
)
?
_key
+
" IS NULL"
:
[
_key
,
_value
].
join
(
"="
))
if
(
options
.
offset
)
{
query
+=
" OFFSET "
+
options
.
offset
}
}
return
result
.
join
(
' AND '
)
return
query
;
},
attributesToSQL
:
function
(
attributes
)
{
...
...
test/associations/multiple-level-filters.test.js
View file @
916a803
...
...
@@ -21,36 +21,27 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this
.
sequelize
.
sync
({
force
:
true
}).
success
(
function
()
{
User
.
bulkCreate
([{
id
:
101
,
username
:
'leia'
},
{
id
:
102
,
username
:
'vader'
}]).
success
(
function
()
{
Project
.
bulkCreate
([{
id
:
201
,
UserId
:
101
,
UserId
:
1
,
title
:
'republic'
},{
id
:
202
,
UserId
:
102
,
title
:
'empire'
}]).
success
(
function
()
{
Task
.
bulkCreate
([{
id
:
301
,
ProjectId
:
201
,
ProjectId
:
1
,
title
:
'fight empire'
},{
id
:
302
,
ProjectId
:
201
,
ProjectId
:
1
,
title
:
'stablish republic'
},{
id
:
303
,
ProjectId
:
202
,
ProjectId
:
2
,
title
:
'destroy rebel alliance'
},{
id
:
304
,
ProjectId
:
202
,
ProjectId
:
2
,
title
:
'rule everything'
}]).
success
(
function
()
{
Task
.
findAll
({
...
...
@@ -87,42 +78,34 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this
.
sequelize
.
sync
({
force
:
true
}).
success
(
function
()
{
User
.
bulkCreate
([{
id
:
101
,
username
:
'leia'
},
{
id
:
102
,
username
:
'vader'
}]).
success
(
function
()
{
Project
.
bulkCreate
([{
id
:
201
,
UserId
:
101
,
UserId
:
1
,
title
:
'republic'
},{
id
:
202
,
UserId
:
102
,
UserId
:
2
,
title
:
'empire'
}]).
success
(
function
()
{
Task
.
bulkCreate
([{
id
:
301
,
ProjectId
:
201
,
ProjectId
:
1
,
title
:
'fight empire'
},{
id
:
302
,
ProjectId
:
201
,
ProjectId
:
1
,
title
:
'stablish republic'
},{
id
:
303
,
ProjectId
:
202
,
ProjectId
:
2
,
title
:
'destroy rebel alliance'
},{
id
:
304
,
ProjectId
:
202
,
ProjectId
:
2
,
title
:
'rule everything'
}]).
success
(
function
()
{
Task
.
findAll
({
where
:
{
'project.user.username'
:
'leia'
,
'project.user.id'
:
1
01
'project.user.id'
:
1
}
}).
success
(
function
(
tasks
){
try
{
...
...
@@ -154,36 +137,28 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this
.
sequelize
.
sync
({
force
:
true
}).
success
(
function
()
{
User
.
bulkCreate
([{
id
:
101
,
username
:
'leia'
},
{
id
:
102
,
username
:
'vader'
}]).
success
(
function
()
{
Project
.
bulkCreate
([{
id
:
201
,
UserId
:
101
,
UserId
:
1
,
title
:
'republic'
},{
id
:
202
,
UserId
:
102
,
UserId
:
2
,
title
:
'empire'
}]).
success
(
function
()
{
Task
.
bulkCreate
([{
id
:
301
,
ProjectId
:
201
,
ProjectId
:
1
,
title
:
'fight empire'
},{
id
:
302
,
ProjectId
:
201
,
ProjectId
:
1
,
title
:
'stablish republic'
},{
id
:
303
,
ProjectId
:
202
,
ProjectId
:
2
,
title
:
'destroy rebel alliance'
},{
id
:
304
,
ProjectId
:
202
,
ProjectId
:
2
,
title
:
'rule everything'
}]).
success
(
function
()
{
User
.
findAll
({
...
...
@@ -214,25 +189,21 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this
.
sequelize
.
sync
({
force
:
true
}).
success
(
function
()
{
User
.
bulkCreate
([{
id
:
101
,
username
:
'leia'
},
{
id
:
102
,
username
:
'vader'
}]).
success
(
function
()
{
Project
.
bulkCreate
([{
id
:
201
,
title
:
'republic'
},{
id
:
202
,
title
:
'empire'
}]).
success
(
function
()
{
User
.
find
(
1
01
).
success
(
function
(
user
){
Project
.
find
(
20
1
).
success
(
function
(
project
){
User
.
find
(
1
).
success
(
function
(
user
){
Project
.
find
(
1
).
success
(
function
(
project
){
user
.
setProjects
([
project
]).
success
(
function
(){
User
.
find
(
10
2
).
success
(
function
(
user
){
Project
.
find
(
2
02
).
success
(
function
(
project
){
User
.
find
(
2
).
success
(
function
(
user
){
Project
.
find
(
2
).
success
(
function
(
project
){
user
.
setProjects
([
project
]).
success
(
function
(){
User
.
findAll
({
where
:
{
...
...
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