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
Hide 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 {
static
formatBindParameters
(
sql
,
values
,
dialect
)
{
const
bindParam
=
[];
const
replacementFunc
=
(
match
,
key
,
val
)
=>
{
if
(
val
[
key
]
!==
undefined
)
{
bindParam
.
push
(
val
[
key
]);
const
replacementFunc
=
(
match
,
key
,
val
ues_
)
=>
{
if
(
val
ues_
[
key
]
!==
undefined
)
{
bindParam
.
push
(
val
ues_
[
key
]);
return
'?'
;
}
return
undefined
;
};
sql
=
AbstractQuery
.
formatBindParameters
(
sql
,
values
,
dialect
,
replacementFunc
)[
0
];
sql
=
AbstractQuery
.
formatBindParameters
(
sql
,
values
,
dialect
,
replacementFunc
)[
0
];
return
[
sql
,
bindParam
.
length
>
0
?
bindParam
:
undefined
];
}
...
...
@@ -35,14 +34,14 @@ class Query extends AbstractQuery {
this
.
sql
=
sql
;
const
{
connection
,
options
}
=
this
;
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
||
options
.
showWarnings
;
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
||
options
.
showWarnings
;
const
complete
=
this
.
_logQuery
(
sql
,
debug
,
parameters
);
if
(
parameters
)
{
debug
(
'parameters(%j)'
,
parameters
);
}
let
results
;
try
{
...
...
@@ -120,13 +119,14 @@ class Query extends AbstractQuery {
if
(
!
this
.
instance
)
{
// handle bulkCreate AI primary key
if
(
this
.
model
if
(
this
.
model
&&
this
.
model
.
autoIncrementAttribute
&&
this
.
model
.
autoIncrementAttribute
===
this
.
model
.
primaryKeyAttribute
&&
this
.
model
.
rawAttributes
[
this
.
model
.
primaryKeyAttribute
]
)
{
//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 ...
//
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...)
const
startId
=
data
[
this
.
getInsertIdField
()];
result
=
new
Array
(
data
.
affectedRows
);
const
pkField
=
this
.
model
.
rawAttributes
[
this
.
model
.
primaryKeyAttribute
].
field
;
...
...
@@ -195,7 +195,7 @@ class Query extends AbstractQuery {
for
(
const
_field
of
Object
.
keys
(
this
.
model
.
fieldRawAttributesMap
))
{
const
modelField
=
this
.
model
.
fieldRawAttributesMap
[
_field
];
if
(
modelField
.
type
instanceof
DataTypes
.
JSON
)
{
//
value is return as String, no
JSON
//
Value is returned as String, not
JSON
rows
=
rows
.
map
(
row
=>
{
row
[
modelField
.
fieldName
]
=
row
[
modelField
.
fieldName
]
?
JSON
.
parse
(
row
[
modelField
.
fieldName
])
:
null
;
...
...
@@ -211,12 +211,10 @@ class Query extends AbstractQuery {
async
logWarnings
(
results
)
{
const
warningResults
=
await
this
.
run
(
'SHOW WARNINGS'
);
const
warningMessage
=
`MariaDB Warnings (
${
this
.
connection
.
uuid
||
'default'
}
): `
;
const
warningMessage
=
`MariaDB Warnings (
${
this
.
connection
.
uuid
||
'default'
}
): `
;
const
messages
=
[];
for
(
const
_warningRow
of
warningResults
)
{
if
(
_warningRow
===
undefined
||
typeof
_warningRow
[
Symbol
.
iterator
]
!==
'function'
)
{
if
(
_warningRow
===
undefined
||
typeof
_warningRow
[
Symbol
.
iterator
]
!==
'function'
)
{
continue
;
}
for
(
const
_warningResult
of
_warningRow
)
{
...
...
@@ -224,8 +222,7 @@ class Query extends AbstractQuery {
messages
.
push
(
_warningResult
.
Message
);
}
else
{
for
(
const
_objectKey
of
_warningResult
.
keys
())
{
messages
.
push
(
[
_objectKey
,
_warningResult
[
_objectKey
]].
join
(
': '
));
messages
.
push
([
_objectKey
,
_warningResult
[
_objectKey
]].
join
(
': '
));
}
}
}
...
...
@@ -250,9 +247,7 @@ class Query extends AbstractQuery {
const
uniqueKey
=
this
.
model
&&
this
.
model
.
uniqueKeys
[
fieldKey
];
if
(
uniqueKey
)
{
if
(
uniqueKey
.
msg
)
{
message
=
uniqueKey
.
msg
;
}
if
(
uniqueKey
.
msg
)
message
=
uniqueKey
.
msg
;
fields
=
_
.
zipObject
(
uniqueKey
.
fields
,
values
);
}
else
{
fields
[
fieldKey
]
=
fieldVal
;
...
...
@@ -270,24 +265,23 @@ class Query extends AbstractQuery {
));
});
return
new
sequelizeErrors
.
UniqueConstraintError
(
{
message
,
errors
,
parent
:
err
,
fields
});
return
new
sequelizeErrors
.
UniqueConstraintError
({
message
,
errors
,
parent
:
err
,
fields
});
}
case
ER_ROW_IS_REFERENCED
:
case
ER_NO_REFERENCED_ROW
:
{
// 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\)
/
);
/CONSTRAINT
([
`"
])(
.*
)\1
FOREIGN KEY
\(\1(
.*
)\1\)
REFERENCES
\1(
.*
)\1
\(\1(
.*
)\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
({
reltype
:
err
.
errno
===
1451
?
'parent'
:
'child'
,
reltype
:
err
.
errno
===
ER_ROW_IS_REFERENCED
?
'parent'
:
'child'
,
table
:
match
?
match
[
4
]
:
undefined
,
fields
,
value
:
fields
&&
fields
.
length
&&
this
.
instance
&&
this
.
instance
[
fields
[
0
]]
||
undefined
,
value
:
fields
&&
fields
.
length
&&
this
.
instance
&&
this
.
instance
[
fields
[
0
]]
||
undefined
,
index
:
match
?
match
[
2
]
:
undefined
,
parent
:
err
});
...
...
lib/dialects/mysql/query.js
View file @
4063c2a
...
...
@@ -5,8 +5,11 @@ const sequelizeErrors = require('../../errors');
const
_
=
require
(
'lodash'
);
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
{
constructor
(
connection
,
sequelize
,
options
)
{
...
...
@@ -15,9 +18,9 @@ class Query extends AbstractQuery {
static
formatBindParameters
(
sql
,
values
,
dialect
)
{
const
bindParam
=
[];
const
replacementFunc
=
(
match
,
key
,
values
)
=>
{
if
(
values
[
key
]
!==
undefined
)
{
bindParam
.
push
(
values
[
key
]);
const
replacementFunc
=
(
match
,
key
,
values
_
)
=>
{
if
(
values
_
[
key
]
!==
undefined
)
{
bindParam
.
push
(
values
_
[
key
]);
return
'?'
;
}
return
undefined
;
...
...
@@ -30,37 +33,46 @@ class Query extends AbstractQuery {
this
.
sql
=
sql
;
const
{
connection
,
options
}
=
this
;
//do we need benchmark for this query execution
const
showWarnings
=
this
.
sequelize
.
options
.
showWarnings
||
options
.
showWarnings
;
const
complete
=
this
.
_logQuery
(
sql
,
debug
,
parameters
);
const
query
=
parameters
&&
parameters
.
length
?
new
Promise
((
resolve
,
reject
)
=>
connection
.
execute
(
sql
,
parameters
,
(
error
,
result
)
=>
error
?
reject
(
error
)
:
resolve
(
result
)).
setMaxListeners
(
100
))
:
new
Promise
((
resolve
,
reject
)
=>
connection
.
query
({
sql
},
(
error
,
result
)
=>
error
?
reject
(
error
)
:
resolve
(
result
)).
setMaxListeners
(
100
));
if
(
parameters
)
{
debug
(
'parameters(%j)'
,
parameters
);
}
let
results
;
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
)
{
// MySQL automatically rolls-back transactions in the event of a deadlock
if
(
options
.
transaction
&&
err
.
errno
===
1213
)
{
options
.
transaction
.
finished
=
'rollback'
;
}
err
.
sql
=
sql
;
err
.
parameters
=
parameters
;
throw
this
.
formatError
(
err
);
}
complete
();
// Log warnings if we've got them.
if
(
showWarnings
&&
results
&&
results
.
warningStatus
>
0
)
{
await
this
.
logWarnings
(
results
);
}
// Return formatted results...
return
this
.
formatResults
(
results
);
}
...
...
@@ -88,7 +100,7 @@ class Query extends AbstractQuery {
this
.
handleInsertQuery
(
data
);
if
(
!
this
.
instance
)
{
// handle bulkCreate AI prim
i
ary key
// handle bulkCreate AI primary key
if
(
data
.
constructor
.
name
===
'ResultSetHeader'
&&
this
.
model
...
...
@@ -123,7 +135,8 @@ class Query extends AbstractQuery {
allowNull
:
_result
.
Null
===
'YES'
,
defaultValue
:
_result
.
Default
,
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
};
}
...
...
@@ -166,7 +179,9 @@ class Query extends AbstractQuery {
const
warningMessage
=
`MySQL Warnings (
${
this
.
connection
.
uuid
||
'default'
}
): `
;
const
messages
=
[];
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
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
_warningResult
,
'Message'
))
{
messages
.
push
(
_warningResult
.
Message
);
...
...
@@ -187,7 +202,7 @@ class Query extends AbstractQuery {
const
errCode
=
err
.
errno
||
err
.
code
;
switch
(
errCode
)
{
case
1062
:
{
case
ER_DUP_ENTRY
:
{
const
match
=
err
.
message
.
match
(
/Duplicate entry '
([\s\S]
*
)
' for key '
?((
.|
\s)
*
?)
'
?
$/
);
let
fields
=
{};
let
message
=
'Validation error'
;
...
...
@@ -218,15 +233,17 @@ class Query extends AbstractQuery {
return
new
sequelizeErrors
.
UniqueConstraintError
({
message
,
errors
,
parent
:
err
,
fields
});
}
case
1451
:
case
1452
:
{
case
ER_ROW_IS_REFERENCED
:
case
ER_NO_REFERENCED_ROW
:
{
// 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
fields
=
match
?
match
[
3
].
split
(
new
RegExp
(
`
${
quoteChar
}
, *
${
quoteChar
}
`
))
:
undefined
;
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
,
fields
,
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