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 4063c2ab
authored
Jan 27, 2021
by
Pedro Augusto de Paula Barbosa
Committed by
GitHub
Jan 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor(query): similar code for mysql and mariadb (#12981)
1 parent
e45df29d
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
59 additions
and
48 deletions
lib/dialects/mariadb/query.js
lib/dialects/mysql/query.js
lib/dialects/mariadb/query.js
View file @
4063c2a
...
@@ -19,15 +19,14 @@ class Query extends AbstractQuery {
...
@@ -19,15 +19,14 @@ class Query extends AbstractQuery {
static
formatBindParameters
(
sql
,
values
,
dialect
)
{
static
formatBindParameters
(
sql
,
values
,
dialect
)
{
const
bindParam
=
[];
const
bindParam
=
[];
const
replacementFunc
=
(
match
,
key
,
val
)
=>
{
const
replacementFunc
=
(
match
,
key
,
val
ues_
)
=>
{
if
(
val
[
key
]
!==
undefined
)
{
if
(
val
ues_
[
key
]
!==
undefined
)
{
bindParam
.
push
(
val
[
key
]);
bindParam
.
push
(
val
ues_
[
key
]);
return
'?'
;
return
'?'
;
}
}
return
undefined
;
return
undefined
;
};
};
sql
=
AbstractQuery
.
formatBindParameters
(
sql
,
values
,
dialect
,
sql
=
AbstractQuery
.
formatBindParameters
(
sql
,
values
,
dialect
,
replacementFunc
)[
0
];
replacementFunc
)[
0
];
return
[
sql
,
bindParam
.
length
>
0
?
bindParam
:
undefined
];
return
[
sql
,
bindParam
.
length
>
0
?
bindParam
:
undefined
];
}
}
...
@@ -35,14 +34,14 @@ class Query extends AbstractQuery {
...
@@ -35,14 +34,14 @@ class Query extends AbstractQuery {
this
.
sql
=
sql
;
this
.
sql
=
sql
;
const
{
connection
,
options
}
=
this
;
const
{
connection
,
options
}
=
this
;
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
||
options
.
showWarnings
;
||
options
.
showWarnings
;
const
complete
=
this
.
_logQuery
(
sql
,
debug
,
parameters
);
const
complete
=
this
.
_logQuery
(
sql
,
debug
,
parameters
);
if
(
parameters
)
{
if
(
parameters
)
{
debug
(
'parameters(%j)'
,
parameters
);
debug
(
'parameters(%j)'
,
parameters
);
}
}
let
results
;
let
results
;
try
{
try
{
...
@@ -120,13 +119,14 @@ class Query extends AbstractQuery {
...
@@ -120,13 +119,14 @@ class Query extends AbstractQuery {
if
(
!
this
.
instance
)
{
if
(
!
this
.
instance
)
{
// handle bulkCreate AI primary key
// handle bulkCreate AI primary key
if
(
this
.
model
if
(
this
.
model
&&
this
.
model
.
autoIncrementAttribute
&&
this
.
model
.
autoIncrementAttribute
&&
this
.
model
.
autoIncrementAttribute
===
this
.
model
.
primaryKeyAttribute
&&
this
.
model
.
autoIncrementAttribute
===
this
.
model
.
primaryKeyAttribute
&&
this
.
model
.
rawAttributes
[
this
.
model
.
primaryKeyAttribute
]
&&
this
.
model
.
rawAttributes
[
this
.
model
.
primaryKeyAttribute
]
)
{
)
{
//ONLY TRUE IF @auto_increment_increment is set to 1 !!
//
ONLY TRUE IF @auto_increment_increment is set to 1 !!
//
Doesn't work with GALERA => each node will reserve increment (x for first server, x+1 for next node ...
//
Doesn't work with GALERA => each node will reserve increment (x for first server, x+1 for next node...)
const
startId
=
data
[
this
.
getInsertIdField
()];
const
startId
=
data
[
this
.
getInsertIdField
()];
result
=
new
Array
(
data
.
affectedRows
);
result
=
new
Array
(
data
.
affectedRows
);
const
pkField
=
this
.
model
.
rawAttributes
[
this
.
model
.
primaryKeyAttribute
].
field
;
const
pkField
=
this
.
model
.
rawAttributes
[
this
.
model
.
primaryKeyAttribute
].
field
;
...
@@ -195,7 +195,7 @@ class Query extends AbstractQuery {
...
@@ -195,7 +195,7 @@ class Query extends AbstractQuery {
for
(
const
_field
of
Object
.
keys
(
this
.
model
.
fieldRawAttributesMap
))
{
for
(
const
_field
of
Object
.
keys
(
this
.
model
.
fieldRawAttributesMap
))
{
const
modelField
=
this
.
model
.
fieldRawAttributesMap
[
_field
];
const
modelField
=
this
.
model
.
fieldRawAttributesMap
[
_field
];
if
(
modelField
.
type
instanceof
DataTypes
.
JSON
)
{
if
(
modelField
.
type
instanceof
DataTypes
.
JSON
)
{
//
value is return as String, no
JSON
//
Value is returned as String, not
JSON
rows
=
rows
.
map
(
row
=>
{
rows
=
rows
.
map
(
row
=>
{
row
[
modelField
.
fieldName
]
=
row
[
modelField
.
fieldName
]
?
JSON
.
parse
(
row
[
modelField
.
fieldName
]
=
row
[
modelField
.
fieldName
]
?
JSON
.
parse
(
row
[
modelField
.
fieldName
])
:
null
;
row
[
modelField
.
fieldName
])
:
null
;
...
@@ -211,12 +211,10 @@ class Query extends AbstractQuery {
...
@@ -211,12 +211,10 @@ class Query extends AbstractQuery {
async
logWarnings
(
results
)
{
async
logWarnings
(
results
)
{
const
warningResults
=
await
this
.
run
(
'SHOW WARNINGS'
);
const
warningResults
=
await
this
.
run
(
'SHOW WARNINGS'
);
const
warningMessage
=
`MariaDB Warnings (
${
this
.
connection
.
uuid
const
warningMessage
=
`MariaDB Warnings (
${
this
.
connection
.
uuid
||
'default'
}
): `
;
||
'default'
}
): `
;
const
messages
=
[];
const
messages
=
[];
for
(
const
_warningRow
of
warningResults
)
{
for
(
const
_warningRow
of
warningResults
)
{
if
(
_warningRow
===
undefined
||
typeof
_warningRow
[
Symbol
.
iterator
]
if
(
_warningRow
===
undefined
||
typeof
_warningRow
[
Symbol
.
iterator
]
!==
'function'
)
{
!==
'function'
)
{
continue
;
continue
;
}
}
for
(
const
_warningResult
of
_warningRow
)
{
for
(
const
_warningResult
of
_warningRow
)
{
...
@@ -224,8 +222,7 @@ class Query extends AbstractQuery {
...
@@ -224,8 +222,7 @@ class Query extends AbstractQuery {
messages
.
push
(
_warningResult
.
Message
);
messages
.
push
(
_warningResult
.
Message
);
}
else
{
}
else
{
for
(
const
_objectKey
of
_warningResult
.
keys
())
{
for
(
const
_objectKey
of
_warningResult
.
keys
())
{
messages
.
push
(
messages
.
push
([
_objectKey
,
_warningResult
[
_objectKey
]].
join
(
': '
));
[
_objectKey
,
_warningResult
[
_objectKey
]].
join
(
': '
));
}
}
}
}
}
}
...
@@ -250,9 +247,7 @@ class Query extends AbstractQuery {
...
@@ -250,9 +247,7 @@ class Query extends AbstractQuery {
const
uniqueKey
=
this
.
model
&&
this
.
model
.
uniqueKeys
[
fieldKey
];
const
uniqueKey
=
this
.
model
&&
this
.
model
.
uniqueKeys
[
fieldKey
];
if
(
uniqueKey
)
{
if
(
uniqueKey
)
{
if
(
uniqueKey
.
msg
)
{
if
(
uniqueKey
.
msg
)
message
=
uniqueKey
.
msg
;
message
=
uniqueKey
.
msg
;
}
fields
=
_
.
zipObject
(
uniqueKey
.
fields
,
values
);
fields
=
_
.
zipObject
(
uniqueKey
.
fields
,
values
);
}
else
{
}
else
{
fields
[
fieldKey
]
=
fieldVal
;
fields
[
fieldKey
]
=
fieldVal
;
...
@@ -270,24 +265,23 @@ class Query extends AbstractQuery {
...
@@ -270,24 +265,23 @@ class Query extends AbstractQuery {
));
));
});
});
return
new
sequelizeErrors
.
UniqueConstraintError
(
return
new
sequelizeErrors
.
UniqueConstraintError
({
message
,
errors
,
parent
:
err
,
fields
});
{
message
,
errors
,
parent
:
err
,
fields
});
}
}
case
ER_ROW_IS_REFERENCED
:
case
ER_ROW_IS_REFERENCED
:
case
ER_NO_REFERENCED_ROW
:
{
case
ER_NO_REFERENCED_ROW
:
{
// e.g. CONSTRAINT `example_constraint_name` FOREIGN KEY (`example_id`) REFERENCES `examples` (`id`)
// e.g. CONSTRAINT `example_constraint_name` FOREIGN KEY (`example_id`) REFERENCES `examples` (`id`)
const
match
=
err
.
message
.
match
(
const
match
=
err
.
message
.
match
(
/CONSTRAINT
([
`"
])(
.*
)\1
FOREIGN KEY
\(\1(
.*
)\1\)
REFERENCES
\1(
.*
)\1
\(\1(
.*
)\1\)
/
);
/CONSTRAINT
([
`"
])(
.*
)\1
FOREIGN KEY
\(\1(
.*
)\1\)
REFERENCES
\1(
.*
)\1
\(\1(
.*
)\1\)
/
);
const
quoteChar
=
match
?
match
[
1
]
:
'`'
;
const
quoteChar
=
match
?
match
[
1
]
:
'`'
;
const
fields
=
match
?
match
[
3
].
split
(
const
fields
=
match
?
match
[
3
].
split
(
new
RegExp
(
`
${
quoteChar
}
, *
${
quoteChar
}
`
))
:
undefined
;
new
RegExp
(
`
${
quoteChar
}
, *
${
quoteChar
}
`
))
:
undefined
;
return
new
sequelizeErrors
.
ForeignKeyConstraintError
({
return
new
sequelizeErrors
.
ForeignKeyConstraintError
({
reltype
:
err
.
errno
===
1451
?
'parent'
:
'child'
,
reltype
:
err
.
errno
===
ER_ROW_IS_REFERENCED
?
'parent'
:
'child'
,
table
:
match
?
match
[
4
]
:
undefined
,
table
:
match
?
match
[
4
]
:
undefined
,
fields
,
fields
,
value
:
fields
&&
fields
.
length
&&
this
.
instance
value
:
fields
&&
fields
.
length
&&
this
.
instance
&&
this
.
instance
[
fields
[
0
]]
||
undefined
,
&&
this
.
instance
[
fields
[
0
]]
||
undefined
,
index
:
match
?
match
[
2
]
:
undefined
,
index
:
match
?
match
[
2
]
:
undefined
,
parent
:
err
parent
:
err
});
});
...
...
lib/dialects/mysql/query.js
View file @
4063c2a
...
@@ -5,8 +5,11 @@ const sequelizeErrors = require('../../errors');
...
@@ -5,8 +5,11 @@ const sequelizeErrors = require('../../errors');
const
_
=
require
(
'lodash'
);
const
_
=
require
(
'lodash'
);
const
{
logger
}
=
require
(
'../../utils/logger'
);
const
{
logger
}
=
require
(
'../../utils/logger'
);
const
debug
=
logger
.
debugContext
(
'sql:mysql'
);
const
ER_DUP_ENTRY
=
1062
;
const
ER_ROW_IS_REFERENCED
=
1451
;
const
ER_NO_REFERENCED_ROW
=
1452
;
const
debug
=
logger
.
debugContext
(
'sql:mysql'
);
class
Query
extends
AbstractQuery
{
class
Query
extends
AbstractQuery
{
constructor
(
connection
,
sequelize
,
options
)
{
constructor
(
connection
,
sequelize
,
options
)
{
...
@@ -15,9 +18,9 @@ class Query extends AbstractQuery {
...
@@ -15,9 +18,9 @@ class Query extends AbstractQuery {
static
formatBindParameters
(
sql
,
values
,
dialect
)
{
static
formatBindParameters
(
sql
,
values
,
dialect
)
{
const
bindParam
=
[];
const
bindParam
=
[];
const
replacementFunc
=
(
match
,
key
,
values
)
=>
{
const
replacementFunc
=
(
match
,
key
,
values
_
)
=>
{
if
(
values
[
key
]
!==
undefined
)
{
if
(
values
_
[
key
]
!==
undefined
)
{
bindParam
.
push
(
values
[
key
]);
bindParam
.
push
(
values
_
[
key
]);
return
'?'
;
return
'?'
;
}
}
return
undefined
;
return
undefined
;
...
@@ -30,37 +33,46 @@ class Query extends AbstractQuery {
...
@@ -30,37 +33,46 @@ class Query extends AbstractQuery {
this
.
sql
=
sql
;
this
.
sql
=
sql
;
const
{
connection
,
options
}
=
this
;
const
{
connection
,
options
}
=
this
;
//do we need benchmark for this query execution
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
||
options
.
showWarnings
;
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
||
options
.
showWarnings
;
const
complete
=
this
.
_logQuery
(
sql
,
debug
,
parameters
);
const
complete
=
this
.
_logQuery
(
sql
,
debug
,
parameters
);
const
query
=
parameters
&&
parameters
.
length
if
(
parameters
)
{
?
new
Promise
((
resolve
,
reject
)
=>
connection
.
execute
(
sql
,
parameters
,
(
error
,
result
)
=>
error
?
reject
(
error
)
:
resolve
(
result
)).
setMaxListeners
(
100
))
debug
(
'parameters(%j)'
,
parameters
);
:
new
Promise
((
resolve
,
reject
)
=>
connection
.
query
({
sql
},
(
error
,
result
)
=>
error
?
reject
(
error
)
:
resolve
(
result
)).
setMaxListeners
(
100
));
}
let
results
;
let
results
;
try
{
try
{
results
=
await
query
;
if
(
parameters
&&
parameters
.
length
)
{
results
=
await
new
Promise
((
resolve
,
reject
)
=>
{
connection
.
execute
(
sql
,
parameters
,
(
error
,
result
)
=>
error
?
reject
(
error
)
:
resolve
(
result
))
.
setMaxListeners
(
100
);
});
}
else
{
results
=
await
new
Promise
((
resolve
,
reject
)
=>
{
connection
.
query
({
sql
},
(
error
,
result
)
=>
error
?
reject
(
error
)
:
resolve
(
result
))
.
setMaxListeners
(
100
);
});
}
}
catch
(
err
)
{
}
catch
(
err
)
{
// MySQL automatically rolls-back transactions in the event of a deadlock
// MySQL automatically rolls-back transactions in the event of a deadlock
if
(
options
.
transaction
&&
err
.
errno
===
1213
)
{
if
(
options
.
transaction
&&
err
.
errno
===
1213
)
{
options
.
transaction
.
finished
=
'rollback'
;
options
.
transaction
.
finished
=
'rollback'
;
}
}
err
.
sql
=
sql
;
err
.
sql
=
sql
;
err
.
parameters
=
parameters
;
err
.
parameters
=
parameters
;
throw
this
.
formatError
(
err
);
throw
this
.
formatError
(
err
);
}
}
complete
();
complete
();
// Log warnings if we've got them.
if
(
showWarnings
&&
results
&&
results
.
warningStatus
>
0
)
{
if
(
showWarnings
&&
results
&&
results
.
warningStatus
>
0
)
{
await
this
.
logWarnings
(
results
);
await
this
.
logWarnings
(
results
);
}
}
// Return formatted results...
return
this
.
formatResults
(
results
);
return
this
.
formatResults
(
results
);
}
}
...
@@ -88,7 +100,7 @@ class Query extends AbstractQuery {
...
@@ -88,7 +100,7 @@ class Query extends AbstractQuery {
this
.
handleInsertQuery
(
data
);
this
.
handleInsertQuery
(
data
);
if
(
!
this
.
instance
)
{
if
(
!
this
.
instance
)
{
// handle bulkCreate AI prim
i
ary key
// handle bulkCreate AI primary key
if
(
if
(
data
.
constructor
.
name
===
'ResultSetHeader'
data
.
constructor
.
name
===
'ResultSetHeader'
&&
this
.
model
&&
this
.
model
...
@@ -123,7 +135,8 @@ class Query extends AbstractQuery {
...
@@ -123,7 +135,8 @@ class Query extends AbstractQuery {
allowNull
:
_result
.
Null
===
'YES'
,
allowNull
:
_result
.
Null
===
'YES'
,
defaultValue
:
_result
.
Default
,
defaultValue
:
_result
.
Default
,
primaryKey
:
_result
.
Key
===
'PRI'
,
primaryKey
:
_result
.
Key
===
'PRI'
,
autoIncrement
:
Object
.
prototype
.
hasOwnProperty
.
call
(
_result
,
'Extra'
)
&&
_result
.
Extra
.
toLowerCase
()
===
'auto_increment'
,
autoIncrement
:
Object
.
prototype
.
hasOwnProperty
.
call
(
_result
,
'Extra'
)
&&
_result
.
Extra
.
toLowerCase
()
===
'auto_increment'
,
comment
:
_result
.
Comment
?
_result
.
Comment
:
null
comment
:
_result
.
Comment
?
_result
.
Comment
:
null
};
};
}
}
...
@@ -166,7 +179,9 @@ class Query extends AbstractQuery {
...
@@ -166,7 +179,9 @@ class Query extends AbstractQuery {
const
warningMessage
=
`MySQL Warnings (
${
this
.
connection
.
uuid
||
'default'
}
): `
;
const
warningMessage
=
`MySQL Warnings (
${
this
.
connection
.
uuid
||
'default'
}
): `
;
const
messages
=
[];
const
messages
=
[];
for
(
const
_warningRow
of
warningResults
)
{
for
(
const
_warningRow
of
warningResults
)
{
if
(
_warningRow
===
undefined
||
typeof
_warningRow
[
Symbol
.
iterator
]
!==
'function'
)
continue
;
if
(
_warningRow
===
undefined
||
typeof
_warningRow
[
Symbol
.
iterator
]
!==
'function'
)
{
continue
;
}
for
(
const
_warningResult
of
_warningRow
)
{
for
(
const
_warningResult
of
_warningRow
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
_warningResult
,
'Message'
))
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
_warningResult
,
'Message'
))
{
messages
.
push
(
_warningResult
.
Message
);
messages
.
push
(
_warningResult
.
Message
);
...
@@ -187,7 +202,7 @@ class Query extends AbstractQuery {
...
@@ -187,7 +202,7 @@ class Query extends AbstractQuery {
const
errCode
=
err
.
errno
||
err
.
code
;
const
errCode
=
err
.
errno
||
err
.
code
;
switch
(
errCode
)
{
switch
(
errCode
)
{
case
1062
:
{
case
ER_DUP_ENTRY
:
{
const
match
=
err
.
message
.
match
(
/Duplicate entry '
([\s\S]
*
)
' for key '
?((
.|
\s)
*
?)
'
?
$/
);
const
match
=
err
.
message
.
match
(
/Duplicate entry '
([\s\S]
*
)
' for key '
?((
.|
\s)
*
?)
'
?
$/
);
let
fields
=
{};
let
fields
=
{};
let
message
=
'Validation error'
;
let
message
=
'Validation error'
;
...
@@ -218,15 +233,17 @@ class Query extends AbstractQuery {
...
@@ -218,15 +233,17 @@ class Query extends AbstractQuery {
return
new
sequelizeErrors
.
UniqueConstraintError
({
message
,
errors
,
parent
:
err
,
fields
});
return
new
sequelizeErrors
.
UniqueConstraintError
({
message
,
errors
,
parent
:
err
,
fields
});
}
}
case
1451
:
case
ER_ROW_IS_REFERENCED
:
case
1452
:
{
case
ER_NO_REFERENCED_ROW
:
{
// e.g. CONSTRAINT `example_constraint_name` FOREIGN KEY (`example_id`) REFERENCES `examples` (`id`)
// e.g. CONSTRAINT `example_constraint_name` FOREIGN KEY (`example_id`) REFERENCES `examples` (`id`)
const
match
=
err
.
message
.
match
(
/CONSTRAINT
([
`"
])(
.*
)\1
FOREIGN KEY
\(\1(
.*
)\1\)
REFERENCES
\1(
.*
)\1
\(\1(
.*
)\1\)
/
);
const
match
=
err
.
message
.
match
(
/CONSTRAINT
([
`"
])(
.*
)\1
FOREIGN KEY
\(\1(
.*
)\1\)
REFERENCES
\1(
.*
)\1
\(\1(
.*
)\1\)
/
);
const
quoteChar
=
match
?
match
[
1
]
:
'`'
;
const
quoteChar
=
match
?
match
[
1
]
:
'`'
;
const
fields
=
match
?
match
[
3
].
split
(
new
RegExp
(
`
${
quoteChar
}
, *
${
quoteChar
}
`
))
:
undefined
;
const
fields
=
match
?
match
[
3
].
split
(
new
RegExp
(
`
${
quoteChar
}
, *
${
quoteChar
}
`
))
:
undefined
;
return
new
sequelizeErrors
.
ForeignKeyConstraintError
({
return
new
sequelizeErrors
.
ForeignKeyConstraintError
({
reltype
:
String
(
errCode
)
===
'1451'
?
'parent'
:
'child'
,
reltype
:
String
(
errCode
)
===
String
(
ER_ROW_IS_REFERENCED
)
?
'parent'
:
'child'
,
table
:
match
?
match
[
4
]
:
undefined
,
table
:
match
?
match
[
4
]
:
undefined
,
fields
,
fields
,
value
:
fields
&&
fields
.
length
&&
this
.
instance
&&
this
.
instance
[
fields
[
0
]]
||
undefined
,
value
:
fields
&&
fields
.
length
&&
this
.
instance
&&
this
.
instance
[
fields
[
0
]]
||
undefined
,
...
...
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