@depup/mysql2 3.22.0-depup.0 → 3.23.2-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/changes.json +8 -3
- package/lib/base/connection.js +4 -2
- package/lib/base/pool.js +4 -0
- package/lib/commands/client_handshake.js +26 -2
- package/lib/commands/execute.js +17 -4
- package/lib/commands/ping.js +1 -1
- package/lib/commands/prepare.js +10 -2
- package/lib/commands/query.js +2 -1
- package/lib/compressed_protocol.js +1 -1
- package/lib/connection_config.js +1 -0
- package/lib/constants/charset_encodings.js +25 -1
- package/lib/constants/mariadb_client.js +19 -0
- package/lib/packets/binary_row.js +2 -2
- package/lib/packets/binlog_query_statusvars.js +1 -1
- package/lib/packets/change_user.js +1 -1
- package/lib/packets/column_definition.js +35 -1
- package/lib/packets/encode_parameter.js +12 -2
- package/lib/packets/execute.js +8 -2
- package/lib/packets/handshake.js +13 -1
- package/lib/packets/handshake_response.js +5 -1
- package/lib/packets/packet.js +51 -3
- package/lib/packets/resultset_header.js +1 -1
- package/lib/packets/ssl_request.js +6 -1
- package/lib/packets/text_row.js +1 -1
- package/lib/parsers/binary_parser.js +45 -6
- package/lib/parsers/parser_cache.js +3 -0
- package/lib/parsers/static_binary_parser.js +37 -2
- package/lib/parsers/static_text_parser.js +21 -2
- package/lib/parsers/text_parser.js +15 -9
- package/lib/promise/capture_local_err.js +25 -0
- package/lib/promise/connection.js +35 -40
- package/lib/promise/make_done_cb.js +5 -9
- package/lib/promise/pool.js +11 -9
- package/lib/promise/pool_cluster.js +9 -2
- package/lib/promise/prepared_statement_info.js +5 -1
- package/package.json +13 -8
- package/promise.js +16 -15
- package/typings/mysql/lib/Connection.d.ts +7 -1
- package/typings/mysql/lib/parsers/typeCast.d.ts +11 -0
- package/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +11 -0
- package/typings/mysql/lib/protocol/sequences/Query.d.ts +7 -1
|
@@ -4,9 +4,10 @@ const ClientConstants = require('../constants/client');
|
|
|
4
4
|
const Packet = require('../packets/packet');
|
|
5
5
|
|
|
6
6
|
class SSLRequest {
|
|
7
|
-
constructor(flags, charset) {
|
|
7
|
+
constructor(flags, charset, mariadbExtendedClientFlags) {
|
|
8
8
|
this.clientFlags = flags | ClientConstants.SSL;
|
|
9
9
|
this.charset = charset;
|
|
10
|
+
this.mariadbExtendedClientFlags = mariadbExtendedClientFlags || 0;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
toPacket() {
|
|
@@ -18,6 +19,10 @@ class SSLRequest {
|
|
|
18
19
|
packet.writeInt32(this.clientFlags);
|
|
19
20
|
packet.writeInt32(0); // max packet size. todo: move to config
|
|
20
21
|
packet.writeInt8(this.charset);
|
|
22
|
+
// the last 4 of the 23 reserved bytes carry the MariaDB extended client
|
|
23
|
+
// capabilities (zero when not negotiated, i.e. plain filler)
|
|
24
|
+
packet.skip(19);
|
|
25
|
+
packet.writeInt32(this.mariadbExtendedClientFlags);
|
|
21
26
|
return packet;
|
|
22
27
|
}
|
|
23
28
|
}
|
package/lib/packets/text_row.js
CHANGED
|
@@ -17,7 +17,7 @@ class TextRow {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
static toPacket(columns, encoding) {
|
|
20
|
-
const sequenceId = 0; // TODO remove, this is calculated now in
|
|
20
|
+
const sequenceId = 0; // TODO remove, this is calculated now in connection
|
|
21
21
|
let length = 0;
|
|
22
22
|
columns.forEach((val) => {
|
|
23
23
|
if (val === null || typeof val === 'undefined') {
|
|
@@ -21,6 +21,13 @@ function readCodeFor(field, config, options, fieldNum) {
|
|
|
21
21
|
const timezone = options.timezone || config.timezone;
|
|
22
22
|
const dateStrings = options.dateStrings || config.dateStrings;
|
|
23
23
|
const unsigned = field.flags & FieldFlags.UNSIGNED;
|
|
24
|
+
// MariaDB sends JSON values as LONGTEXT; the JSON type is only visible in
|
|
25
|
+
// the extended metadata (MARIADB_CLIENT_EXTENDED_METADATA capability)
|
|
26
|
+
if (field.extendedFormat === 'json') {
|
|
27
|
+
return config.jsonStrings
|
|
28
|
+
? `packet.readLengthCodedString(fields[${fieldNum}].encoding)`
|
|
29
|
+
: `packet.parseJson(fields[${fieldNum}].encoding, ${supportBigNumbers});`;
|
|
30
|
+
}
|
|
24
31
|
switch (field.columnType) {
|
|
25
32
|
case Types.TINY:
|
|
26
33
|
return unsigned ? 'packet.readInt8();' : 'packet.readSInt8();';
|
|
@@ -63,7 +70,7 @@ function readCodeFor(field, config, options, fieldNum) {
|
|
|
63
70
|
// see https://github.com/sidorares/node-mysql2/issues/409
|
|
64
71
|
return config.jsonStrings
|
|
65
72
|
? 'packet.readLengthCodedString("utf8")'
|
|
66
|
-
:
|
|
73
|
+
: `packet.parseJson("utf8", ${supportBigNumbers});`;
|
|
67
74
|
case Types.LONGLONG:
|
|
68
75
|
if (!supportBigNumbers) {
|
|
69
76
|
return unsigned
|
|
@@ -89,13 +96,21 @@ function compile(fields, options, config) {
|
|
|
89
96
|
const parserFn = genFunc();
|
|
90
97
|
const nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8);
|
|
91
98
|
|
|
92
|
-
function
|
|
99
|
+
function fieldMetadata(field) {
|
|
93
100
|
return {
|
|
94
101
|
type: typeNames[field.columnType],
|
|
102
|
+
extendedTypeName: field.extendedTypeName,
|
|
103
|
+
extendedFormat: field.extendedFormat,
|
|
95
104
|
length: field.columnLength,
|
|
96
105
|
db: field.schema,
|
|
97
106
|
table: field.table,
|
|
98
107
|
name: field.name,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function wrap(field, packet) {
|
|
112
|
+
return {
|
|
113
|
+
...fieldMetadata(field),
|
|
99
114
|
string: function (encoding = field.encoding) {
|
|
100
115
|
if (field.columnType === Types.JSON && encoding === field.encoding) {
|
|
101
116
|
// Since for JSON columns mysql always returns charset 63 (BINARY),
|
|
@@ -139,6 +154,22 @@ function compile(fields, options, config) {
|
|
|
139
154
|
};
|
|
140
155
|
}
|
|
141
156
|
|
|
157
|
+
/** A NULL value carries no bytes in the binary row packet, so the accessors return null without reading from it. */
|
|
158
|
+
function wrapNull(field) {
|
|
159
|
+
return {
|
|
160
|
+
...fieldMetadata(field),
|
|
161
|
+
string: function () {
|
|
162
|
+
return null;
|
|
163
|
+
},
|
|
164
|
+
buffer: function () {
|
|
165
|
+
return null;
|
|
166
|
+
},
|
|
167
|
+
geometry: function () {
|
|
168
|
+
return null;
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
142
173
|
parserFn('(function(){');
|
|
143
174
|
parserFn('return class BinaryRow {');
|
|
144
175
|
parserFn('constructor() {');
|
|
@@ -187,9 +218,17 @@ function compile(fields, options, config) {
|
|
|
187
218
|
lvalue = `result[${fieldName}]`;
|
|
188
219
|
}
|
|
189
220
|
|
|
190
|
-
parserFn(`if (nullBitmaskByte${nullByteIndex} & ${currentFieldNullBit}) `);
|
|
191
|
-
|
|
192
|
-
|
|
221
|
+
parserFn(`if (nullBitmaskByte${nullByteIndex} & ${currentFieldNullBit}) {`);
|
|
222
|
+
if (typeof options.typeCast === 'function') {
|
|
223
|
+
const nullWrapperVar = `nullWrapper${i}`;
|
|
224
|
+
parserFn(`const ${nullWrapperVar} = wrapNull(fields[${i}]);`);
|
|
225
|
+
parserFn(
|
|
226
|
+
`${lvalue} = options.typeCast(${nullWrapperVar}, function() { return null; });`
|
|
227
|
+
);
|
|
228
|
+
} else {
|
|
229
|
+
parserFn(`${lvalue} = null;`);
|
|
230
|
+
}
|
|
231
|
+
parserFn('} else {');
|
|
193
232
|
|
|
194
233
|
if (options.typeCast === false) {
|
|
195
234
|
parserFn(`${lvalue} = packet.readLengthCodedBuffer();`);
|
|
@@ -225,7 +264,7 @@ function compile(fields, options, config) {
|
|
|
225
264
|
parserFn.toString()
|
|
226
265
|
);
|
|
227
266
|
}
|
|
228
|
-
return parserFn.toFunction({ wrap });
|
|
267
|
+
return parserFn.toFunction({ wrap, wrapNull });
|
|
229
268
|
}
|
|
230
269
|
|
|
231
270
|
function getBinaryParser(fields, options, config) {
|
|
@@ -20,6 +20,7 @@ function keyFromFields(type, fields, options, config) {
|
|
|
20
20
|
options.timezone || config.timezone,
|
|
21
21
|
Boolean(options.decimalNumbers),
|
|
22
22
|
options.dateStrings,
|
|
23
|
+
Boolean(config.jsonStrings),
|
|
23
24
|
];
|
|
24
25
|
|
|
25
26
|
for (let i = 0; i < fields.length; ++i) {
|
|
@@ -33,6 +34,8 @@ function keyFromFields(type, fields, options, config) {
|
|
|
33
34
|
field.table,
|
|
34
35
|
field.flags,
|
|
35
36
|
field.characterSet,
|
|
37
|
+
field.extendedTypeName,
|
|
38
|
+
field.extendedFormat,
|
|
36
39
|
]);
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -22,6 +22,14 @@ function getBinaryParser(fields, _options, config) {
|
|
|
22
22
|
const dateStrings = options.dateStrings || config.dateStrings;
|
|
23
23
|
const unsigned = field.flags & FieldFlags.UNSIGNED;
|
|
24
24
|
|
|
25
|
+
// MariaDB sends JSON values as LONGTEXT; the JSON type is only visible in
|
|
26
|
+
// the extended metadata (MARIADB_CLIENT_EXTENDED_METADATA capability)
|
|
27
|
+
if (field.extendedFormat === 'json') {
|
|
28
|
+
return config.jsonStrings
|
|
29
|
+
? packet.readLengthCodedString(field.encoding)
|
|
30
|
+
: packet.parseJson(field.encoding, supportBigNumbers);
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
switch (field.columnType) {
|
|
26
34
|
case Types.TINY:
|
|
27
35
|
return unsigned ? packet.readInt8() : packet.readSInt8();
|
|
@@ -66,7 +74,7 @@ function getBinaryParser(fields, _options, config) {
|
|
|
66
74
|
// see https://github.com/sidorares/node-mysql2/issues/409
|
|
67
75
|
return config.jsonStrings
|
|
68
76
|
? packet.readLengthCodedString('utf8')
|
|
69
|
-
:
|
|
77
|
+
: packet.parseJson('utf8', supportBigNumbers);
|
|
70
78
|
case Types.LONGLONG:
|
|
71
79
|
if (!supportBigNumbers)
|
|
72
80
|
return unsigned
|
|
@@ -86,6 +94,28 @@ function getBinaryParser(fields, _options, config) {
|
|
|
86
94
|
}
|
|
87
95
|
}
|
|
88
96
|
|
|
97
|
+
/** A NULL value carries no bytes in the binary row packet, so the accessors return null without reading from it. */
|
|
98
|
+
function wrapNull(field) {
|
|
99
|
+
return {
|
|
100
|
+
type: typeNames[field.columnType],
|
|
101
|
+
extendedTypeName: field.extendedTypeName,
|
|
102
|
+
extendedFormat: field.extendedFormat,
|
|
103
|
+
length: field.columnLength,
|
|
104
|
+
db: field.schema,
|
|
105
|
+
table: field.table,
|
|
106
|
+
name: field.name,
|
|
107
|
+
string: function () {
|
|
108
|
+
return null;
|
|
109
|
+
},
|
|
110
|
+
buffer: function () {
|
|
111
|
+
return null;
|
|
112
|
+
},
|
|
113
|
+
geometry: function () {
|
|
114
|
+
return null;
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
89
119
|
return class BinaryRow {
|
|
90
120
|
constructor() {}
|
|
91
121
|
|
|
@@ -110,7 +140,10 @@ function getBinaryParser(fields, _options, config) {
|
|
|
110
140
|
|
|
111
141
|
let value;
|
|
112
142
|
if (nullBitmaskBytes[nullByteIndex] & currentFieldNullBit) {
|
|
113
|
-
value =
|
|
143
|
+
value =
|
|
144
|
+
typeof typeCast === 'function'
|
|
145
|
+
? typeCast(wrapNull(field), () => null)
|
|
146
|
+
: null;
|
|
114
147
|
} else if (options.typeCast === false) {
|
|
115
148
|
value = packet.readLengthCodedBuffer();
|
|
116
149
|
} else {
|
|
@@ -120,6 +153,8 @@ function getBinaryParser(fields, _options, config) {
|
|
|
120
153
|
? typeCast(
|
|
121
154
|
{
|
|
122
155
|
type: typeNames[field.columnType],
|
|
156
|
+
extendedTypeName: field.extendedTypeName,
|
|
157
|
+
extendedFormat: field.extendedFormat,
|
|
123
158
|
length: field.columnLength,
|
|
124
159
|
db: field.schema,
|
|
125
160
|
table: field.table,
|
|
@@ -9,7 +9,15 @@ for (const t in Types) {
|
|
|
9
9
|
typeNames[Types[t]] = t;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
function readField({
|
|
12
|
+
function readField({
|
|
13
|
+
packet,
|
|
14
|
+
field,
|
|
15
|
+
type,
|
|
16
|
+
charset,
|
|
17
|
+
encoding,
|
|
18
|
+
config,
|
|
19
|
+
options,
|
|
20
|
+
}) {
|
|
13
21
|
const supportBigNumbers = Boolean(
|
|
14
22
|
options.supportBigNumbers || config.supportBigNumbers
|
|
15
23
|
);
|
|
@@ -19,6 +27,14 @@ function readField({ packet, type, charset, encoding, config, options }) {
|
|
|
19
27
|
const timezone = options.timezone || config.timezone;
|
|
20
28
|
const dateStrings = options.dateStrings || config.dateStrings;
|
|
21
29
|
|
|
30
|
+
// MariaDB sends JSON values as LONGTEXT; the JSON type is only visible in
|
|
31
|
+
// the extended metadata (MARIADB_CLIENT_EXTENDED_METADATA capability)
|
|
32
|
+
if (field.extendedFormat === 'json') {
|
|
33
|
+
return config.jsonStrings
|
|
34
|
+
? packet.readLengthCodedString(encoding)
|
|
35
|
+
: packet.parseJson(encoding, supportBigNumbers);
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
switch (type) {
|
|
23
39
|
case Types.TINY:
|
|
24
40
|
case Types.SHORT:
|
|
@@ -64,7 +80,7 @@ function readField({ packet, type, charset, encoding, config, options }) {
|
|
|
64
80
|
// see https://github.com/sidorares/node-mysql2/issues/409
|
|
65
81
|
return config.jsonStrings
|
|
66
82
|
? packet.readLengthCodedString('utf8')
|
|
67
|
-
:
|
|
83
|
+
: packet.parseJson('utf8', supportBigNumbers);
|
|
68
84
|
default:
|
|
69
85
|
if (charset === Charsets.BINARY) {
|
|
70
86
|
return packet.readLengthCodedBuffer();
|
|
@@ -76,6 +92,8 @@ function readField({ packet, type, charset, encoding, config, options }) {
|
|
|
76
92
|
function createTypecastField(field, packet) {
|
|
77
93
|
return {
|
|
78
94
|
type: typeNames[field.columnType],
|
|
95
|
+
extendedTypeName: field.extendedTypeName,
|
|
96
|
+
extendedFormat: field.extendedFormat,
|
|
79
97
|
length: field.columnLength,
|
|
80
98
|
db: field.schema,
|
|
81
99
|
table: field.table,
|
|
@@ -110,6 +128,7 @@ function getTextParser(_fields, _options, config) {
|
|
|
110
128
|
const next = () =>
|
|
111
129
|
readField({
|
|
112
130
|
packet,
|
|
131
|
+
field,
|
|
113
132
|
type: field.columnType,
|
|
114
133
|
encoding: field.encoding,
|
|
115
134
|
charset: field.characterSet,
|
|
@@ -11,7 +11,9 @@ for (const t in Types) {
|
|
|
11
11
|
typeNames[Types[t]] = t;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function readCodeFor(
|
|
14
|
+
function readCodeFor(field, encodingExpr, config, options) {
|
|
15
|
+
const type = field.columnType;
|
|
16
|
+
const charset = field.characterSet;
|
|
15
17
|
const supportBigNumbers = Boolean(
|
|
16
18
|
options.supportBigNumbers || config.supportBigNumbers
|
|
17
19
|
);
|
|
@@ -21,6 +23,14 @@ function readCodeFor(type, charset, encodingExpr, config, options) {
|
|
|
21
23
|
const timezone = options.timezone || config.timezone;
|
|
22
24
|
const dateStrings = options.dateStrings || config.dateStrings;
|
|
23
25
|
|
|
26
|
+
// MariaDB sends JSON values as LONGTEXT; the JSON type is only visible in
|
|
27
|
+
// the extended metadata (MARIADB_CLIENT_EXTENDED_METADATA capability)
|
|
28
|
+
if (field.extendedFormat === 'json') {
|
|
29
|
+
return config.jsonStrings
|
|
30
|
+
? `packet.readLengthCodedString(${encodingExpr})`
|
|
31
|
+
: `packet.parseJson(${encodingExpr}, ${supportBigNumbers})`;
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
switch (type) {
|
|
25
35
|
case Types.TINY:
|
|
26
36
|
case Types.SHORT:
|
|
@@ -67,7 +77,7 @@ function readCodeFor(type, charset, encodingExpr, config, options) {
|
|
|
67
77
|
// see https://github.com/sidorares/node-mysql2/issues/409
|
|
68
78
|
return config.jsonStrings
|
|
69
79
|
? 'packet.readLengthCodedString("utf8")'
|
|
70
|
-
:
|
|
80
|
+
: `packet.parseJson("utf8", ${supportBigNumbers})`;
|
|
71
81
|
default:
|
|
72
82
|
if (charset === Charsets.BINARY) {
|
|
73
83
|
return 'packet.readLengthCodedBuffer()';
|
|
@@ -88,6 +98,8 @@ function compile(fields, options, config) {
|
|
|
88
98
|
function wrap(field, _this) {
|
|
89
99
|
return {
|
|
90
100
|
type: typeNames[field.columnType],
|
|
101
|
+
extendedTypeName: field.extendedTypeName,
|
|
102
|
+
extendedFormat: field.extendedFormat,
|
|
91
103
|
length: field.columnLength,
|
|
92
104
|
db: field.schema,
|
|
93
105
|
table: field.table,
|
|
@@ -174,13 +186,7 @@ function compile(fields, options, config) {
|
|
|
174
186
|
parserFn(`${lvalue} = packet.readLengthCodedBuffer();`);
|
|
175
187
|
} else {
|
|
176
188
|
const encodingExpr = `fields[${i}].encoding`;
|
|
177
|
-
const readCode = readCodeFor(
|
|
178
|
-
fields[i].columnType,
|
|
179
|
-
fields[i].characterSet,
|
|
180
|
-
encodingExpr,
|
|
181
|
-
config,
|
|
182
|
-
options
|
|
183
|
-
);
|
|
189
|
+
const readCode = readCodeFor(fields[i], encodingExpr, config, options);
|
|
184
190
|
if (typeof options.typeCast === 'function') {
|
|
185
191
|
parserFn(
|
|
186
192
|
`${lvalue} = options.typeCast(this.wrap${i}, function() { return ${readCode} });`
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** @param {Function} constructorOpt Passed to Error.captureStackTrace (omit this frame from stacks). */
|
|
4
|
+
function captureStackHolder(constructorOpt) {
|
|
5
|
+
const holder = {};
|
|
6
|
+
Error.captureStackTrace(holder, constructorOpt);
|
|
7
|
+
return holder;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Replace `err.stack` frames with the capture from `holder`, keeping the
|
|
12
|
+
* callback error instance and its MySQL fields.
|
|
13
|
+
*
|
|
14
|
+
* @param {Error} err
|
|
15
|
+
* @param {{ stack?: string }} holder
|
|
16
|
+
*/
|
|
17
|
+
function applyCapturedStack(err, holder) {
|
|
18
|
+
const stack = holder && holder.stack;
|
|
19
|
+
if (typeof stack !== 'string' || !stack) return;
|
|
20
|
+
const lines = stack.split('\n');
|
|
21
|
+
lines[0] = `${err.name}: ${err.message}`;
|
|
22
|
+
err.stack = lines.join('\n');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = { captureStackHolder, applyCapturedStack };
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const EventEmitter = require('events').EventEmitter;
|
|
4
4
|
const PromisePreparedStatementInfo = require('./prepared_statement_info.js');
|
|
5
|
+
const {
|
|
6
|
+
captureStackHolder,
|
|
7
|
+
applyCapturedStack,
|
|
8
|
+
} = require('./capture_local_err.js');
|
|
5
9
|
const makeDoneCb = require('./make_done_cb.js');
|
|
6
10
|
const inheritEvents = require('./inherit_events.js');
|
|
7
11
|
const BaseConnection = require('../base/connection.js');
|
|
@@ -26,13 +30,14 @@ class PromiseConnection extends EventEmitter {
|
|
|
26
30
|
|
|
27
31
|
query(query, params) {
|
|
28
32
|
const c = this.connection;
|
|
33
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.query);
|
|
29
34
|
if (typeof params === 'function') {
|
|
30
35
|
throw new Error(
|
|
31
36
|
'Callback function is not available with promise clients.'
|
|
32
37
|
);
|
|
33
38
|
}
|
|
34
39
|
return new this.Promise((resolve, reject) => {
|
|
35
|
-
const done = makeDoneCb(resolve, reject);
|
|
40
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
36
41
|
if (params !== undefined) {
|
|
37
42
|
c.query(query, params, done);
|
|
38
43
|
} else {
|
|
@@ -43,13 +48,14 @@ class PromiseConnection extends EventEmitter {
|
|
|
43
48
|
|
|
44
49
|
execute(query, params) {
|
|
45
50
|
const c = this.connection;
|
|
51
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.execute);
|
|
46
52
|
if (typeof params === 'function') {
|
|
47
53
|
throw new Error(
|
|
48
54
|
'Callback function is not available with promise clients.'
|
|
49
55
|
);
|
|
50
56
|
}
|
|
51
57
|
return new this.Promise((resolve, reject) => {
|
|
52
|
-
const done = makeDoneCb(resolve, reject);
|
|
58
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
53
59
|
if (params !== undefined) {
|
|
54
60
|
c.execute(query, params, done);
|
|
55
61
|
} else {
|
|
@@ -72,40 +78,43 @@ class PromiseConnection extends EventEmitter {
|
|
|
72
78
|
|
|
73
79
|
beginTransaction() {
|
|
74
80
|
const c = this.connection;
|
|
81
|
+
const stackHolder = captureStackHolder(
|
|
82
|
+
PromiseConnection.prototype.beginTransaction
|
|
83
|
+
);
|
|
75
84
|
return new this.Promise((resolve, reject) => {
|
|
76
|
-
const done = makeDoneCb(resolve, reject);
|
|
85
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
77
86
|
c.beginTransaction(done);
|
|
78
87
|
});
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
commit() {
|
|
82
91
|
const c = this.connection;
|
|
92
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.commit);
|
|
83
93
|
return new this.Promise((resolve, reject) => {
|
|
84
|
-
const done = makeDoneCb(resolve, reject);
|
|
94
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
85
95
|
c.commit(done);
|
|
86
96
|
});
|
|
87
97
|
}
|
|
88
98
|
|
|
89
99
|
rollback() {
|
|
90
100
|
const c = this.connection;
|
|
101
|
+
const stackHolder = captureStackHolder(
|
|
102
|
+
PromiseConnection.prototype.rollback
|
|
103
|
+
);
|
|
91
104
|
return new this.Promise((resolve, reject) => {
|
|
92
|
-
const done = makeDoneCb(resolve, reject);
|
|
105
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
93
106
|
c.rollback(done);
|
|
94
107
|
});
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
ping() {
|
|
98
111
|
const c = this.connection;
|
|
112
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.ping);
|
|
99
113
|
return new this.Promise((resolve, reject) => {
|
|
100
114
|
c.ping((err) => {
|
|
101
115
|
if (err) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
localErr.code = err.code;
|
|
105
|
-
localErr.errno = err.errno;
|
|
106
|
-
localErr.sqlState = err.sqlState;
|
|
107
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
108
|
-
reject(localErr);
|
|
116
|
+
applyCapturedStack(err, stackHolder);
|
|
117
|
+
reject(err);
|
|
109
118
|
} else {
|
|
110
119
|
resolve(true);
|
|
111
120
|
}
|
|
@@ -115,16 +124,12 @@ class PromiseConnection extends EventEmitter {
|
|
|
115
124
|
|
|
116
125
|
reset() {
|
|
117
126
|
const c = this.connection;
|
|
127
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.reset);
|
|
118
128
|
return new this.Promise((resolve, reject) => {
|
|
119
129
|
c.reset((err) => {
|
|
120
130
|
if (err) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
localErr.code = err.code;
|
|
124
|
-
localErr.errno = err.errno;
|
|
125
|
-
localErr.sqlState = err.sqlState;
|
|
126
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
127
|
-
reject(localErr);
|
|
131
|
+
applyCapturedStack(err, stackHolder);
|
|
132
|
+
reject(err);
|
|
128
133
|
} else {
|
|
129
134
|
resolve();
|
|
130
135
|
}
|
|
@@ -134,16 +139,12 @@ class PromiseConnection extends EventEmitter {
|
|
|
134
139
|
|
|
135
140
|
connect() {
|
|
136
141
|
const c = this.connection;
|
|
142
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.connect);
|
|
137
143
|
return new this.Promise((resolve, reject) => {
|
|
138
144
|
c.connect((err, param) => {
|
|
139
145
|
if (err) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
localErr.code = err.code;
|
|
143
|
-
localErr.errno = err.errno;
|
|
144
|
-
localErr.sqlState = err.sqlState;
|
|
145
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
146
|
-
reject(localErr);
|
|
146
|
+
applyCapturedStack(err, stackHolder);
|
|
147
|
+
reject(err);
|
|
147
148
|
} else {
|
|
148
149
|
resolve(param);
|
|
149
150
|
}
|
|
@@ -154,16 +155,12 @@ class PromiseConnection extends EventEmitter {
|
|
|
154
155
|
prepare(options) {
|
|
155
156
|
const c = this.connection;
|
|
156
157
|
const promiseImpl = this.Promise;
|
|
158
|
+
const stackHolder = captureStackHolder(PromiseConnection.prototype.prepare);
|
|
157
159
|
return new this.Promise((resolve, reject) => {
|
|
158
160
|
c.prepare(options, (err, statement) => {
|
|
159
161
|
if (err) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
localErr.code = err.code;
|
|
163
|
-
localErr.errno = err.errno;
|
|
164
|
-
localErr.sqlState = err.sqlState;
|
|
165
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
166
|
-
reject(localErr);
|
|
162
|
+
applyCapturedStack(err, stackHolder);
|
|
163
|
+
reject(err);
|
|
167
164
|
} else {
|
|
168
165
|
const wrappedStatement = new PromisePreparedStatementInfo(
|
|
169
166
|
statement,
|
|
@@ -177,16 +174,14 @@ class PromiseConnection extends EventEmitter {
|
|
|
177
174
|
|
|
178
175
|
changeUser(options) {
|
|
179
176
|
const c = this.connection;
|
|
177
|
+
const stackHolder = captureStackHolder(
|
|
178
|
+
PromiseConnection.prototype.changeUser
|
|
179
|
+
);
|
|
180
180
|
return new this.Promise((resolve, reject) => {
|
|
181
181
|
c.changeUser(options, (err) => {
|
|
182
182
|
if (err) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
localErr.code = err.code;
|
|
186
|
-
localErr.errno = err.errno;
|
|
187
|
-
localErr.sqlState = err.sqlState;
|
|
188
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
189
|
-
reject(localErr);
|
|
183
|
+
applyCapturedStack(err, stackHolder);
|
|
184
|
+
reject(err);
|
|
190
185
|
} else {
|
|
191
186
|
resolve();
|
|
192
187
|
}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const { applyCapturedStack } = require('./capture_local_err.js');
|
|
4
|
+
|
|
5
|
+
function makeDoneCb(resolve, reject, stackHolder) {
|
|
4
6
|
return function (err, rows, fields) {
|
|
5
7
|
if (err) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
localErr.code = err.code;
|
|
9
|
-
localErr.errno = err.errno;
|
|
10
|
-
localErr.sql = err.sql;
|
|
11
|
-
localErr.sqlState = err.sqlState;
|
|
12
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
13
|
-
reject(localErr);
|
|
8
|
+
applyCapturedStack(err, stackHolder);
|
|
9
|
+
reject(err);
|
|
14
10
|
} else {
|
|
15
11
|
resolve([rows, fields]);
|
|
16
12
|
}
|
package/lib/promise/pool.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const EventEmitter = require('events').EventEmitter;
|
|
4
|
+
const {
|
|
5
|
+
captureStackHolder,
|
|
6
|
+
applyCapturedStack,
|
|
7
|
+
} = require('./capture_local_err.js');
|
|
4
8
|
const makeDoneCb = require('./make_done_cb.js');
|
|
5
9
|
const PromisePoolConnection = require('./pool_connection.js');
|
|
6
10
|
const inheritEvents = require('./inherit_events.js');
|
|
@@ -33,13 +37,14 @@ class PromisePool extends EventEmitter {
|
|
|
33
37
|
|
|
34
38
|
query(sql, args) {
|
|
35
39
|
const corePool = this.pool;
|
|
40
|
+
const stackHolder = captureStackHolder(PromisePool.prototype.query);
|
|
36
41
|
if (typeof args === 'function') {
|
|
37
42
|
throw new Error(
|
|
38
43
|
'Callback function is not available with promise clients.'
|
|
39
44
|
);
|
|
40
45
|
}
|
|
41
46
|
return new this.Promise((resolve, reject) => {
|
|
42
|
-
const done = makeDoneCb(resolve, reject);
|
|
47
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
43
48
|
if (args !== undefined) {
|
|
44
49
|
corePool.query(sql, args, done);
|
|
45
50
|
} else {
|
|
@@ -50,13 +55,14 @@ class PromisePool extends EventEmitter {
|
|
|
50
55
|
|
|
51
56
|
execute(sql, args) {
|
|
52
57
|
const corePool = this.pool;
|
|
58
|
+
const stackHolder = captureStackHolder(PromisePool.prototype.execute);
|
|
53
59
|
if (typeof args === 'function') {
|
|
54
60
|
throw new Error(
|
|
55
61
|
'Callback function is not available with promise clients.'
|
|
56
62
|
);
|
|
57
63
|
}
|
|
58
64
|
return new this.Promise((resolve, reject) => {
|
|
59
|
-
const done = makeDoneCb(resolve, reject);
|
|
65
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
60
66
|
if (args) {
|
|
61
67
|
corePool.execute(sql, args, done);
|
|
62
68
|
} else {
|
|
@@ -67,16 +73,12 @@ class PromisePool extends EventEmitter {
|
|
|
67
73
|
|
|
68
74
|
end() {
|
|
69
75
|
const corePool = this.pool;
|
|
76
|
+
const stackHolder = captureStackHolder(PromisePool.prototype.end);
|
|
70
77
|
return new this.Promise((resolve, reject) => {
|
|
71
78
|
corePool.end((err) => {
|
|
72
79
|
if (err) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
localErr.code = err.code;
|
|
76
|
-
localErr.errno = err.errno;
|
|
77
|
-
localErr.sqlState = err.sqlState;
|
|
78
|
-
localErr.sqlMessage = err.sqlMessage;
|
|
79
|
-
reject(localErr);
|
|
80
|
+
applyCapturedStack(err, stackHolder);
|
|
81
|
+
reject(err);
|
|
80
82
|
} else {
|
|
81
83
|
resolve();
|
|
82
84
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { captureStackHolder } = require('./capture_local_err.js');
|
|
3
4
|
const PromisePoolConnection = require('./pool_connection');
|
|
4
5
|
const makeDoneCb = require('./make_done_cb');
|
|
5
6
|
|
|
@@ -24,26 +25,32 @@ class PromisePoolNamespace {
|
|
|
24
25
|
|
|
25
26
|
query(sql, values) {
|
|
26
27
|
const corePoolNamespace = this.poolNamespace;
|
|
28
|
+
const stackHolder = captureStackHolder(
|
|
29
|
+
PromisePoolNamespace.prototype.query
|
|
30
|
+
);
|
|
27
31
|
if (typeof values === 'function') {
|
|
28
32
|
throw new Error(
|
|
29
33
|
'Callback function is not available with promise clients.'
|
|
30
34
|
);
|
|
31
35
|
}
|
|
32
36
|
return new this.Promise((resolve, reject) => {
|
|
33
|
-
const done = makeDoneCb(resolve, reject);
|
|
37
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
34
38
|
corePoolNamespace.query(sql, values, done);
|
|
35
39
|
});
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
execute(sql, values) {
|
|
39
43
|
const corePoolNamespace = this.poolNamespace;
|
|
44
|
+
const stackHolder = captureStackHolder(
|
|
45
|
+
PromisePoolNamespace.prototype.execute
|
|
46
|
+
);
|
|
40
47
|
if (typeof values === 'function') {
|
|
41
48
|
throw new Error(
|
|
42
49
|
'Callback function is not available with promise clients.'
|
|
43
50
|
);
|
|
44
51
|
}
|
|
45
52
|
return new this.Promise((resolve, reject) => {
|
|
46
|
-
const done = makeDoneCb(resolve, reject);
|
|
53
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
47
54
|
corePoolNamespace.execute(sql, values, done);
|
|
48
55
|
});
|
|
49
56
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { captureStackHolder } = require('./capture_local_err.js');
|
|
3
4
|
const makeDoneCb = require('./make_done_cb.js');
|
|
4
5
|
|
|
5
6
|
class PromisePreparedStatementInfo {
|
|
@@ -10,8 +11,11 @@ class PromisePreparedStatementInfo {
|
|
|
10
11
|
|
|
11
12
|
execute(parameters) {
|
|
12
13
|
const s = this.statement;
|
|
14
|
+
const stackHolder = captureStackHolder(
|
|
15
|
+
PromisePreparedStatementInfo.prototype.execute
|
|
16
|
+
);
|
|
13
17
|
return new this.Promise((resolve, reject) => {
|
|
14
|
-
const done = makeDoneCb(resolve, reject);
|
|
18
|
+
const done = makeDoneCb(resolve, reject, stackHolder);
|
|
15
19
|
if (parameters) {
|
|
16
20
|
s.execute(parameters, done);
|
|
17
21
|
} else {
|