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 37087559
authored
Jan 26, 2014
by
Jan Aagaard Meier
Browse files
Options
Browse Files
Download
Plain Diff
Rebase and Merge pull request #1024 from durango/newindex
2 parents
4845800a
8a81de1e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
160 additions
and
8 deletions
lib/dao-factory.js
lib/dao.js
lib/dialects/mariadb/query-generator.js
lib/dialects/mysql/query-generator.js
lib/dialects/postgres/query-generator.js
lib/dialects/sqlite/query-generator.js
test/dao-factory.test.js
lib/dao-factory.js
View file @
3708755
...
@@ -115,10 +115,24 @@ module.exports = (function() {
...
@@ -115,10 +115,24 @@ module.exports = (function() {
})()
})()
DAOFactory
.
prototype
.
init
=
function
(
daoFactoryManager
)
{
DAOFactory
.
prototype
.
init
=
function
(
daoFactoryManager
)
{
var
self
=
this
;
var
self
=
this
this
.
daoFactoryManager
=
daoFactoryManager
this
.
primaryKeys
=
{}
self
.
options
.
uniqueKeys
=
{}
Utils
.
_
.
each
(
this
.
rawAttributes
,
function
(
columnValues
,
columnName
)
{
if
(
columnValues
.
hasOwnProperty
(
'unique'
)
&&
columnValues
.
unique
!==
true
)
{
var
idxName
=
columnValues
.
unique
if
(
typeof
columnValues
.
unique
===
"object"
)
{
idxName
=
columnValues
.
unique
.
name
}
this
.
daoFactoryManager
=
daoFactoryManager
self
.
options
.
uniqueKeys
[
idxName
]
=
self
.
options
.
uniqueKeys
[
idxName
]
||
{
fields
:
[],
msg
:
null
}
this
.
primaryKeys
=
{};
self
.
options
.
uniqueKeys
[
idxName
].
fields
.
push
(
columnName
)
self
.
options
.
uniqueKeys
[
idxName
].
msg
=
self
.
options
.
uniqueKeys
[
idxName
].
msg
||
columnValues
.
unique
.
msg
||
null
}
})
Utils
.
_
.
each
(
this
.
attributes
,
function
(
dataTypeString
,
attributeName
)
{
Utils
.
_
.
each
(
this
.
attributes
,
function
(
dataTypeString
,
attributeName
)
{
if
(
dataTypeString
.
indexOf
(
'PRIMARY KEY'
)
!==
-
1
)
{
if
(
dataTypeString
.
indexOf
(
'PRIMARY KEY'
)
!==
-
1
)
{
...
...
lib/dao.js
View file @
3708755
...
@@ -396,7 +396,23 @@ module.exports = (function() {
...
@@ -396,7 +396,23 @@ module.exports = (function() {
args
[
2
]
=
values
args
[
2
]
=
values
self
.
QueryInterface
[
query
].
apply
(
self
.
QueryInterface
,
args
)
self
.
QueryInterface
[
query
].
apply
(
self
.
QueryInterface
,
args
)
.
proxy
(
emitter
,
{
events
:
[
'sql'
,
'error'
]})
.
proxy
(
emitter
,
{
events
:
[
'sql'
]})
.
error
(
function
(
err
)
{
if
(
!!
self
.
__options
.
uniqueKeys
&&
err
.
code
&&
self
.
QueryInterface
.
QueryGenerator
.
uniqueConstraintMapping
.
code
===
err
.
code
)
{
var
fields
=
self
.
QueryInterface
.
QueryGenerator
.
uniqueConstraintMapping
.
map
(
err
.
toString
())
if
(
fields
!==
false
)
{
fields
=
fields
.
filter
(
function
(
f
)
{
return
f
!==
self
.
daoFactory
.
tableName
;
})
Utils
.
_
.
each
(
self
.
__options
.
uniqueKeys
,
function
(
value
,
key
)
{
if
(
Utils
.
_
.
isEqual
(
value
.
fields
,
fields
)
&&
!!
value
.
msg
)
{
err
=
value
.
msg
}
})
}
}
emitter
.
emit
(
'error'
,
err
)
})
.
success
(
function
(
result
)
{
.
success
(
function
(
result
)
{
// Transfer database generated values (defaults, autoincrement, etc)
// Transfer database generated values (defaults, autoincrement, etc)
values
=
_
.
extend
(
values
,
result
.
dataValues
)
values
=
_
.
extend
(
values
,
result
.
dataValues
)
...
...
lib/dialects/mariadb/query-generator.js
View file @
3708755
...
@@ -2,7 +2,19 @@ var Utils = require("../../utils")
...
@@ -2,7 +2,19 @@ var Utils = require("../../utils")
module
.
exports
=
(
function
()
{
module
.
exports
=
(
function
()
{
var
QueryGenerator
=
{
var
QueryGenerator
=
{
dialect
:
'mariadb'
dialect
:
'mariadb'
,
uniqueConstraintMapping
:
{
code
:
1062
,
map
:
function
(
str
)
{
// we're manually remvoving uniq_ here for a future capability of defining column names explicitly
var
match
=
str
.
replace
(
'uniq_'
,
''
).
match
(
/Duplicate entry .* for key '
(
.*
?)
'$/
)
if
(
match
===
null
||
match
.
length
<
2
)
{
return
false
}
return
match
[
1
].
split
(
'_'
)
}
},
}
}
// "MariaDB is a drop-in replacement for MySQL." - so thats exactly what we do, drop in the mysql query generator
// "MariaDB is a drop-in replacement for MySQL." - so thats exactly what we do, drop in the mysql query generator
...
...
lib/dialects/mysql/query-generator.js
View file @
3708755
...
@@ -76,6 +76,12 @@ module.exports = (function() {
...
@@ -76,6 +76,12 @@ module.exports = (function() {
}
}
,
pkString
=
primaryKeys
.
map
(
function
(
pk
)
{
return
this
.
quoteIdentifier
(
pk
)
}.
bind
(
this
)).
join
(
", "
)
,
pkString
=
primaryKeys
.
map
(
function
(
pk
)
{
return
this
.
quoteIdentifier
(
pk
)
}.
bind
(
this
)).
join
(
", "
)
if
(
!!
options
.
uniqueKeys
)
{
Utils
.
_
.
each
(
options
.
uniqueKeys
,
function
(
columns
)
{
values
.
attributes
+=
", UNIQUE uniq_"
+
tableName
+
'_'
+
columns
.
fields
.
join
(
'_'
)
+
" ("
+
columns
.
fields
.
join
(
', '
)
+
")"
})
}
if
(
pkString
.
length
>
0
)
{
if
(
pkString
.
length
>
0
)
{
values
.
attributes
+=
", PRIMARY KEY ("
+
pkString
+
")"
values
.
attributes
+=
", PRIMARY KEY ("
+
pkString
+
")"
}
}
...
@@ -103,6 +109,19 @@ module.exports = (function() {
...
@@ -103,6 +109,19 @@ module.exports = (function() {
return
'SHOW TABLES;'
return
'SHOW TABLES;'
},
},
uniqueConstraintMapping
:
{
code
:
'ER_DUP_ENTRY'
,
map
:
function
(
str
)
{
// we're manually remvoving uniq_ here for a future capability of defining column names explicitly
var
match
=
str
.
replace
(
'uniq_'
,
''
).
match
(
/Duplicate entry .* for key '
(
.*
?)
'$/
)
if
(
match
===
null
||
match
.
length
<
2
)
{
return
false
}
return
match
[
1
].
split
(
'_'
)
}
},
addColumnQuery
:
function
(
tableName
,
attributes
)
{
addColumnQuery
:
function
(
tableName
,
attributes
)
{
var
query
=
"ALTER TABLE `<%= tableName %>` ADD <%= attributes %>;"
var
query
=
"ALTER TABLE `<%= tableName %>` ADD <%= attributes %>;"
,
attrString
=
[]
,
attrString
=
[]
...
@@ -317,7 +336,7 @@ module.exports = (function() {
...
@@ -317,7 +336,7 @@ module.exports = (function() {
template
+=
" DEFAULT "
+
this
.
escape
(
dataType
.
defaultValue
)
template
+=
" DEFAULT "
+
this
.
escape
(
dataType
.
defaultValue
)
}
}
if
(
dataType
.
unique
)
{
if
(
dataType
.
unique
===
true
)
{
template
+=
" UNIQUE"
template
+=
" UNIQUE"
}
}
...
...
lib/dialects/postgres/query-generator.js
View file @
3708755
...
@@ -44,6 +44,8 @@ module.exports = (function() {
...
@@ -44,6 +44,8 @@ module.exports = (function() {
},
},
createTableQuery
:
function
(
tableName
,
attributes
,
options
)
{
createTableQuery
:
function
(
tableName
,
attributes
,
options
)
{
var
self
=
this
options
=
Utils
.
_
.
extend
({
options
=
Utils
.
_
.
extend
({
},
options
||
{})
},
options
||
{})
...
@@ -76,6 +78,12 @@ module.exports = (function() {
...
@@ -76,6 +78,12 @@ module.exports = (function() {
comments
:
Utils
.
_
.
template
(
comments
,
{
table
:
this
.
quoteIdentifiers
(
tableName
)})
comments
:
Utils
.
_
.
template
(
comments
,
{
table
:
this
.
quoteIdentifiers
(
tableName
)})
}
}
if
(
!!
options
.
uniqueKeys
)
{
Utils
.
_
.
each
(
options
.
uniqueKeys
,
function
(
columns
)
{
values
.
attributes
+=
", UNIQUE ("
+
columns
.
fields
.
map
(
function
(
f
)
{
return
self
.
quoteIdentifiers
(
f
)
}).
join
(
', '
)
+
")"
})
}
var
pks
=
primaryKeys
[
tableName
].
map
(
function
(
pk
){
var
pks
=
primaryKeys
[
tableName
].
map
(
function
(
pk
){
return
this
.
quoteIdentifier
(
pk
)
return
this
.
quoteIdentifier
(
pk
)
}.
bind
(
this
)).
join
(
","
)
}.
bind
(
this
)).
join
(
","
)
...
@@ -114,6 +122,18 @@ module.exports = (function() {
...
@@ -114,6 +122,18 @@ module.exports = (function() {
})
})
},
},
uniqueConstraintMapping
:
{
code
:
'23505'
,
map
:
function
(
str
)
{
var
match
=
str
.
match
(
/duplicate key value violates unique constraint "
(
.*
?)
_key"/
)
if
(
match
===
null
||
match
.
length
<
2
)
{
return
false
}
return
match
[
1
].
split
(
'_'
).
splice
(
1
)
}
},
addColumnQuery
:
function
(
tableName
,
attributes
)
{
addColumnQuery
:
function
(
tableName
,
attributes
)
{
var
query
=
"ALTER TABLE <%= tableName %> ADD COLUMN <%= attributes %>;"
var
query
=
"ALTER TABLE <%= tableName %> ADD COLUMN <%= attributes %>;"
,
attrString
=
[]
,
attrString
=
[]
...
@@ -448,7 +468,7 @@ module.exports = (function() {
...
@@ -448,7 +468,7 @@ module.exports = (function() {
replacements
.
defaultValue
=
this
.
escape
(
dataType
.
defaultValue
)
replacements
.
defaultValue
=
this
.
escape
(
dataType
.
defaultValue
)
}
}
if
(
dataType
.
unique
)
{
if
(
dataType
.
unique
===
true
)
{
template
+=
" UNIQUE"
template
+=
" UNIQUE"
}
}
...
...
lib/dialects/sqlite/query-generator.js
View file @
3708755
...
@@ -109,6 +109,12 @@ module.exports = (function() {
...
@@ -109,6 +109,12 @@ module.exports = (function() {
}
}
,
pkString
=
primaryKeys
.
map
(
function
(
pk
)
{
return
this
.
quoteIdentifier
(
pk
)
}.
bind
(
this
)).
join
(
", "
)
,
pkString
=
primaryKeys
.
map
(
function
(
pk
)
{
return
this
.
quoteIdentifier
(
pk
)
}.
bind
(
this
)).
join
(
", "
)
if
(
!!
options
.
uniqueKeys
)
{
Utils
.
_
.
each
(
options
.
uniqueKeys
,
function
(
columns
)
{
values
.
attributes
+=
", UNIQUE ("
+
columns
.
fields
.
join
(
', '
)
+
")"
})
}
if
(
pkString
.
length
>
0
)
{
if
(
pkString
.
length
>
0
)
{
values
.
attributes
+=
", PRIMARY KEY ("
+
pkString
+
")"
values
.
attributes
+=
", PRIMARY KEY ("
+
pkString
+
")"
}
}
...
@@ -131,6 +137,18 @@ module.exports = (function() {
...
@@ -131,6 +137,18 @@ module.exports = (function() {
})
})
},
},
uniqueConstraintMapping
:
{
code
:
'SQLITE_CONSTRAINT'
,
map
:
function
(
str
)
{
var
match
=
str
.
match
(
/columns
(
.*
?)
are/
)
if
(
match
===
null
||
match
.
length
<
2
)
{
return
false
}
return
match
[
1
].
split
(
', '
)
}
},
addLimitAndOffset
:
function
(
options
,
query
){
addLimitAndOffset
:
function
(
options
,
query
){
query
=
query
||
""
query
=
query
||
""
if
(
options
.
offset
&&
!
options
.
limit
)
{
if
(
options
.
offset
&&
!
options
.
limit
)
{
...
@@ -184,6 +202,26 @@ module.exports = (function() {
...
@@ -184,6 +202,26 @@ module.exports = (function() {
return
Utils
.
_
.
template
(
query
)(
replacements
)
return
Utils
.
_
.
template
(
query
)(
replacements
)
},
},
updateQuery
:
function
(
tableName
,
attrValueHash
,
where
,
options
)
{
attrValueHash
=
Utils
.
removeNullValuesFromHash
(
attrValueHash
,
this
.
options
.
omitNull
,
options
)
var
query
=
"UPDATE <%= table %> SET <%= values %> WHERE <%= where %>"
,
values
=
[]
for
(
var
key
in
attrValueHash
)
{
var
value
=
attrValueHash
[
key
]
values
.
push
(
this
.
quoteIdentifier
(
key
)
+
"="
+
this
.
escape
(
value
))
}
var
replacements
=
{
table
:
this
.
quoteIdentifier
(
tableName
),
values
:
values
.
join
(
","
),
where
:
this
.
getWhereConditions
(
where
)
}
return
Utils
.
_
.
template
(
query
)(
replacements
)
},
deleteQuery
:
function
(
tableName
,
where
,
options
)
{
deleteQuery
:
function
(
tableName
,
where
,
options
)
{
options
=
options
||
{}
options
=
options
||
{}
...
@@ -226,7 +264,7 @@ module.exports = (function() {
...
@@ -226,7 +264,7 @@ module.exports = (function() {
replacements
.
defaultValue
=
this
.
escape
(
dataType
.
defaultValue
)
replacements
.
defaultValue
=
this
.
escape
(
dataType
.
defaultValue
)
}
}
if
(
dataType
.
unique
)
{
if
(
dataType
.
unique
===
true
)
{
template
+=
" UNIQUE"
template
+=
" UNIQUE"
}
}
...
...
test/dao-factory.test.js
View file @
3708755
...
@@ -246,6 +246,39 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
...
@@ -246,6 +246,39 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
})
})
it
(
'allows multiple column unique keys to be defined'
,
function
(
done
)
{
var
User
=
this
.
sequelize
.
define
(
'UserWithUniqueUsername'
,
{
username
:
{
type
:
Sequelize
.
STRING
,
unique
:
'user_and_email'
},
email
:
{
type
:
Sequelize
.
STRING
,
unique
:
'user_and_email'
},
aCol
:
{
type
:
Sequelize
.
STRING
,
unique
:
'a_and_b'
},
bCol
:
{
type
:
Sequelize
.
STRING
,
unique
:
'a_and_b'
}
})
User
.
sync
({
force
:
true
}).
on
(
'sql'
,
function
(
sql
)
{
expect
(
sql
).
to
.
match
(
/UNIQUE
\s
*
(
uniq_UserWithUniqueUsernames_username_email
)?\s
*
\([
`"
]?
username
[
`"
]?
,
[
`"
]?
email
[
`"
]?\)
/
)
expect
(
sql
).
to
.
match
(
/UNIQUE
\s
*
(
uniq_UserWithUniqueUsernames_aCol_bCol
)?\s
*
\([
`"
]?
aCol
[
`"
]?
,
[
`"
]?
bCol
[
`"
]?\)
/
)
done
()
})
})
it
(
'allows us to customize the error message for unique constraint'
,
function
(
done
)
{
var
User
=
this
.
sequelize
.
define
(
'UserWithUniqueUsername'
,
{
username
:
{
type
:
Sequelize
.
STRING
,
unique
:
{
name
:
'user_and_email'
,
msg
:
'User and email must be unique'
}},
email
:
{
type
:
Sequelize
.
STRING
,
unique
:
'user_and_email'
},
aCol
:
{
type
:
Sequelize
.
STRING
,
unique
:
'a_and_b'
},
bCol
:
{
type
:
Sequelize
.
STRING
,
unique
:
'a_and_b'
}
})
User
.
sync
({
force
:
true
}).
success
(
function
()
{
User
.
create
({
username
:
'tobi'
,
email
:
'tobi@tobi.me'
}).
success
(
function
()
{
User
.
create
({
username
:
'tobi'
,
email
:
'tobi@tobi.me'
}).
error
(
function
(
err
)
{
expect
(
err
).
to
.
equal
(
'User and email must be unique'
)
done
()
})
})
})
})
})
})
describe
(
'build'
,
function
()
{
describe
(
'build'
,
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