@depup/mysql2 3.20.0-depup.0 → 3.21.1-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 +2 -2
- package/changes.json +5 -0
- package/lib/commands/execute.js +5 -1
- package/lib/commands/query.js +5 -1
- package/lib/commands/server_handshake.js +4 -1
- package/lib/connection_config.js +1 -0
- package/lib/constants/client.js +1 -0
- package/lib/constants/cursor.js +1 -0
- package/lib/packets/encode_parameter.js +69 -0
- package/lib/packets/execute.js +68 -105
- package/lib/packets/handshake_response.js +2 -2
- package/lib/packets/packet.js +11 -14
- package/lib/packets/query.js +82 -7
- package/lib/packets/resultset_header.js +1 -1
- package/package.json +12 -8
- package/typings/mysql/index.d.ts +4 -0
- package/typings/mysql/lib/protocol/sequences/Query.d.ts +7 -0
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ npm install @depup/mysql2
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [mysql2](https://www.npmjs.com/package/mysql2) @ 3.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [mysql2](https://www.npmjs.com/package/mysql2) @ 3.21.1 |
|
|
17
|
+
| Processed | 2026-04-10 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
19
|
| Deps updated | 0 |
|
|
20
20
|
|
package/changes.json
ADDED
package/lib/commands/execute.js
CHANGED
|
@@ -43,11 +43,15 @@ class Execute extends Command {
|
|
|
43
43
|
this._connection = connection;
|
|
44
44
|
this.options = Object.assign({}, connection.config, this._executeOptions);
|
|
45
45
|
this._setTimeout();
|
|
46
|
+
const clientFlags =
|
|
47
|
+
connection.config.clientFlags & (connection.serverCapabilityFlags || 0);
|
|
46
48
|
const executePacket = new Packets.Execute(
|
|
47
49
|
this.statement.id,
|
|
48
50
|
this.parameters,
|
|
49
51
|
connection.config.charsetNumber,
|
|
50
|
-
connection.config.timezone
|
|
52
|
+
connection.config.timezone,
|
|
53
|
+
this._executeOptions.attributes,
|
|
54
|
+
clientFlags
|
|
51
55
|
);
|
|
52
56
|
//For reasons why this try-catch is here, please see
|
|
53
57
|
// https://github.com/sidorares/node-mysql2/pull/689
|
package/lib/commands/query.js
CHANGED
|
@@ -53,9 +53,13 @@ class Query extends Command {
|
|
|
53
53
|
this.options = Object.assign({}, connection.config, this._queryOptions);
|
|
54
54
|
this._setTimeout();
|
|
55
55
|
|
|
56
|
+
const clientFlags =
|
|
57
|
+
connection.config.clientFlags & (connection.serverCapabilityFlags || 0);
|
|
56
58
|
const cmdPacket = new Packets.Query(
|
|
57
59
|
this.sql,
|
|
58
|
-
connection.config.charsetNumber
|
|
60
|
+
connection.config.charsetNumber,
|
|
61
|
+
this._queryOptions.attributes,
|
|
62
|
+
clientFlags
|
|
59
63
|
);
|
|
60
64
|
connection.writePacket(cmdPacket.toPacket(1));
|
|
61
65
|
return Query.prototype.resultsetHeader;
|
|
@@ -35,7 +35,10 @@ class ServerHandshake extends Command {
|
|
|
35
35
|
|
|
36
36
|
readClientReply(packet, connection) {
|
|
37
37
|
// check auth here
|
|
38
|
-
const clientHelloReply = Packets.HandshakeResponse.fromPacket(
|
|
38
|
+
const clientHelloReply = Packets.HandshakeResponse.fromPacket(
|
|
39
|
+
packet,
|
|
40
|
+
this.args.capabilityFlags
|
|
41
|
+
);
|
|
39
42
|
// TODO check we don't have something similar already
|
|
40
43
|
connection.clientHelloReply = clientHelloReply;
|
|
41
44
|
if (this.args.authCallback) {
|
package/lib/connection_config.js
CHANGED
package/lib/constants/client.js
CHANGED
|
@@ -31,6 +31,7 @@ exports.CONNECT_ATTRS = 0x00100000; /* permits connection attributes */
|
|
|
31
31
|
exports.PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000; /* Understands length-encoded integer for auth response data in Protocol::HandshakeResponse41. */
|
|
32
32
|
exports.CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000; /* Announces support for expired password extension. */
|
|
33
33
|
exports.SESSION_TRACK = 0x00800000; /* Can set SERVER_SESSION_STATE_CHANGED in the Status Flags and send session-state change data after a OK packet. */
|
|
34
|
+
exports.CLIENT_QUERY_ATTRIBUTES = 0x08000000; /* support query attributes in COM_QUERY and COM_STMT_EXECUTE */
|
|
34
35
|
|
|
35
36
|
exports.SSL_VERIFY_SERVER_CERT = 0x40000000;
|
|
36
37
|
exports.REMEMBER_OPTIONS = 0x80000000;
|
package/lib/constants/cursor.js
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Types = require('../constants/types');
|
|
4
|
+
const Packet = require('../packets/packet');
|
|
5
|
+
|
|
6
|
+
function isJSON(value) {
|
|
7
|
+
return (
|
|
8
|
+
Array.isArray(value) ||
|
|
9
|
+
value.constructor === Object ||
|
|
10
|
+
(typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function toParameter(value, encoding, timezone) {
|
|
15
|
+
let type = Types.VAR_STRING;
|
|
16
|
+
let length;
|
|
17
|
+
let writer = function (value) {
|
|
18
|
+
// eslint-disable-next-line no-invalid-this
|
|
19
|
+
return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
|
|
20
|
+
};
|
|
21
|
+
if (value !== null) {
|
|
22
|
+
switch (typeof value) {
|
|
23
|
+
case 'undefined':
|
|
24
|
+
throw new TypeError('Bind parameters must not contain undefined');
|
|
25
|
+
|
|
26
|
+
case 'number':
|
|
27
|
+
type = Types.DOUBLE;
|
|
28
|
+
length = 8;
|
|
29
|
+
writer = Packet.prototype.writeDouble;
|
|
30
|
+
break;
|
|
31
|
+
|
|
32
|
+
case 'boolean':
|
|
33
|
+
value = value | 0;
|
|
34
|
+
type = Types.TINY;
|
|
35
|
+
length = 1;
|
|
36
|
+
writer = Packet.prototype.writeInt8;
|
|
37
|
+
break;
|
|
38
|
+
|
|
39
|
+
case 'object':
|
|
40
|
+
if (Object.prototype.toString.call(value) === '[object Date]') {
|
|
41
|
+
type = Types.DATETIME;
|
|
42
|
+
length = 12;
|
|
43
|
+
writer = function (value) {
|
|
44
|
+
// eslint-disable-next-line no-invalid-this
|
|
45
|
+
return Packet.prototype.writeDate.call(this, value, timezone);
|
|
46
|
+
};
|
|
47
|
+
} else if (isJSON(value)) {
|
|
48
|
+
value = JSON.stringify(value);
|
|
49
|
+
type = Types.JSON;
|
|
50
|
+
} else if (Buffer.isBuffer(value)) {
|
|
51
|
+
length = Packet.lengthCodedNumberLength(value.length) + value.length;
|
|
52
|
+
writer = Packet.prototype.writeLengthCodedBuffer;
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
|
|
56
|
+
default:
|
|
57
|
+
value = value.toString();
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
value = '';
|
|
61
|
+
type = Types.NULL;
|
|
62
|
+
}
|
|
63
|
+
if (!length) {
|
|
64
|
+
length = Packet.lengthCodedStringLength(value, encoding);
|
|
65
|
+
}
|
|
66
|
+
return { value, type, length, writer };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { toParameter, isJSON };
|
package/lib/packets/execute.js
CHANGED
|
@@ -2,83 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
const CursorType = require('../constants/cursor');
|
|
4
4
|
const CommandCodes = require('../constants/commands');
|
|
5
|
+
const ClientConstants = require('../constants/client');
|
|
5
6
|
const Types = require('../constants/types');
|
|
6
7
|
const Packet = require('../packets/packet');
|
|
7
8
|
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
|
8
|
-
|
|
9
|
-
function isJSON(value) {
|
|
10
|
-
return (
|
|
11
|
-
Array.isArray(value) ||
|
|
12
|
-
value.constructor === Object ||
|
|
13
|
-
(typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Converts a value to an object describing type, String/Buffer representation and length
|
|
19
|
-
* @param {*} value
|
|
20
|
-
*/
|
|
21
|
-
function toParameter(value, encoding, timezone) {
|
|
22
|
-
let type = Types.VAR_STRING;
|
|
23
|
-
let length;
|
|
24
|
-
let writer = function (value) {
|
|
25
|
-
// eslint-disable-next-line no-invalid-this
|
|
26
|
-
return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
|
|
27
|
-
};
|
|
28
|
-
if (value !== null) {
|
|
29
|
-
switch (typeof value) {
|
|
30
|
-
case 'undefined':
|
|
31
|
-
throw new TypeError('Bind parameters must not contain undefined');
|
|
32
|
-
|
|
33
|
-
case 'number':
|
|
34
|
-
type = Types.DOUBLE;
|
|
35
|
-
length = 8;
|
|
36
|
-
writer = Packet.prototype.writeDouble;
|
|
37
|
-
break;
|
|
38
|
-
|
|
39
|
-
case 'boolean':
|
|
40
|
-
value = value | 0;
|
|
41
|
-
type = Types.TINY;
|
|
42
|
-
length = 1;
|
|
43
|
-
writer = Packet.prototype.writeInt8;
|
|
44
|
-
break;
|
|
45
|
-
|
|
46
|
-
case 'object':
|
|
47
|
-
if (Object.prototype.toString.call(value) === '[object Date]') {
|
|
48
|
-
type = Types.DATETIME;
|
|
49
|
-
length = 12;
|
|
50
|
-
writer = function (value) {
|
|
51
|
-
// eslint-disable-next-line no-invalid-this
|
|
52
|
-
return Packet.prototype.writeDate.call(this, value, timezone);
|
|
53
|
-
};
|
|
54
|
-
} else if (isJSON(value)) {
|
|
55
|
-
value = JSON.stringify(value);
|
|
56
|
-
type = Types.JSON;
|
|
57
|
-
} else if (Buffer.isBuffer(value)) {
|
|
58
|
-
length = Packet.lengthCodedNumberLength(value.length) + value.length;
|
|
59
|
-
writer = Packet.prototype.writeLengthCodedBuffer;
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
|
|
63
|
-
default:
|
|
64
|
-
value = value.toString();
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
value = '';
|
|
68
|
-
type = Types.NULL;
|
|
69
|
-
}
|
|
70
|
-
if (!length) {
|
|
71
|
-
length = Packet.lengthCodedStringLength(value, encoding);
|
|
72
|
-
}
|
|
73
|
-
return { value, type, length, writer };
|
|
74
|
-
}
|
|
9
|
+
const { toParameter } = require('./encode_parameter.js');
|
|
75
10
|
|
|
76
11
|
class Execute {
|
|
77
|
-
constructor(
|
|
12
|
+
constructor(
|
|
13
|
+
id,
|
|
14
|
+
parameters,
|
|
15
|
+
charsetNumber,
|
|
16
|
+
timezone,
|
|
17
|
+
attributes,
|
|
18
|
+
clientFlags
|
|
19
|
+
) {
|
|
78
20
|
this.id = id;
|
|
79
21
|
this.parameters = parameters;
|
|
80
22
|
this.encoding = CharsetToEncoding[charsetNumber];
|
|
81
23
|
this.timezone = timezone;
|
|
24
|
+
this.attributes = attributes;
|
|
25
|
+
this.clientFlags = clientFlags || 0;
|
|
82
26
|
}
|
|
83
27
|
|
|
84
28
|
static fromPacket(packet, encoding) {
|
|
@@ -145,39 +89,48 @@ class Execute {
|
|
|
145
89
|
return { stmtId, flags, iterationCount, values };
|
|
146
90
|
}
|
|
147
91
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
length += Math.floor((this.parameters.length + 7) / 8);
|
|
160
|
-
length += 1; // new-params-bound-flag
|
|
161
|
-
length += 2 * this.parameters.length; // type byte for each parameter if new-params-bound-flag is set
|
|
162
|
-
parameters = this.parameters.map((value) =>
|
|
163
|
-
toParameter(value, this.encoding, this.timezone)
|
|
164
|
-
);
|
|
165
|
-
length += parameters.reduce(
|
|
166
|
-
(accumulator, parameter) => accumulator + parameter.length,
|
|
167
|
-
0
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
const buffer = Buffer.allocUnsafe(length);
|
|
171
|
-
const packet = new Packet(0, buffer, 0, length);
|
|
92
|
+
_serializeToBuffer(buffer) {
|
|
93
|
+
const useQueryAttributes =
|
|
94
|
+
this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
|
|
95
|
+
|
|
96
|
+
const attrNames =
|
|
97
|
+
useQueryAttributes && this.attributes ? Object.keys(this.attributes) : [];
|
|
98
|
+
const numParams = this.parameters ? this.parameters.length : 0;
|
|
99
|
+
const numAttrs = attrNames.length;
|
|
100
|
+
const totalParams = numParams + numAttrs;
|
|
101
|
+
|
|
102
|
+
const packet = new Packet(0, buffer, 0, buffer.length);
|
|
172
103
|
packet.offset = 4;
|
|
173
104
|
packet.writeInt8(CommandCodes.STMT_EXECUTE);
|
|
174
105
|
packet.writeInt32(this.id);
|
|
175
|
-
|
|
106
|
+
|
|
107
|
+
let cursorFlags = CursorType.NO_CURSOR;
|
|
108
|
+
if (useQueryAttributes) {
|
|
109
|
+
cursorFlags |= CursorType.PARAMETER_COUNT_AVAILABLE;
|
|
110
|
+
}
|
|
111
|
+
packet.writeInt8(cursorFlags);
|
|
176
112
|
packet.writeInt32(1); // iteration-count, always 1
|
|
177
|
-
|
|
113
|
+
|
|
114
|
+
if (useQueryAttributes) {
|
|
115
|
+
packet.writeLengthCodedNumber(totalParams);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (totalParams > 0) {
|
|
119
|
+
const bindParams =
|
|
120
|
+
numParams > 0
|
|
121
|
+
? this.parameters.map((v) =>
|
|
122
|
+
toParameter(v, this.encoding, this.timezone)
|
|
123
|
+
)
|
|
124
|
+
: [];
|
|
125
|
+
const attrParams = attrNames.map((name) =>
|
|
126
|
+
toParameter(this.attributes[name], this.encoding, this.timezone)
|
|
127
|
+
);
|
|
128
|
+
const allParams = bindParams.concat(attrParams);
|
|
129
|
+
|
|
130
|
+
// null bitmap
|
|
178
131
|
let bitmap = 0;
|
|
179
132
|
let bitValue = 1;
|
|
180
|
-
|
|
133
|
+
allParams.forEach((parameter) => {
|
|
181
134
|
if (parameter.type === Types.NULL) {
|
|
182
135
|
bitmap += bitValue;
|
|
183
136
|
}
|
|
@@ -191,24 +144,34 @@ class Execute {
|
|
|
191
144
|
if (bitValue !== 1) {
|
|
192
145
|
packet.writeInt8(bitmap);
|
|
193
146
|
}
|
|
194
|
-
|
|
195
|
-
// afaik, if set n*2 bytes with type of parameter are sent before parameters
|
|
196
|
-
// if not, previous execution types are used (TODO prooflink)
|
|
147
|
+
|
|
197
148
|
packet.writeInt8(1); // new-params-bound-flag
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
packet.writeInt8(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
149
|
+
|
|
150
|
+
// types (and names for attributes)
|
|
151
|
+
for (let i = 0; i < allParams.length; i++) {
|
|
152
|
+
packet.writeInt8(allParams[i].type);
|
|
153
|
+
packet.writeInt8(0); // unsigned flag
|
|
154
|
+
if (useQueryAttributes) {
|
|
155
|
+
const name = i < numParams ? '' : attrNames[i - numParams];
|
|
156
|
+
packet.writeLengthCodedString(name, this.encoding);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// values
|
|
161
|
+
allParams.forEach((parameter) => {
|
|
205
162
|
if (parameter.type !== Types.NULL) {
|
|
206
163
|
parameter.writer.call(packet, parameter.value);
|
|
207
164
|
}
|
|
208
165
|
});
|
|
209
166
|
}
|
|
167
|
+
|
|
210
168
|
return packet;
|
|
211
169
|
}
|
|
170
|
+
|
|
171
|
+
toPacket() {
|
|
172
|
+
const p = this._serializeToBuffer(Packet.MockBuffer());
|
|
173
|
+
return this._serializeToBuffer(Buffer.allocUnsafe(p.offset));
|
|
174
|
+
}
|
|
212
175
|
}
|
|
213
176
|
|
|
214
177
|
module.exports = Execute;
|
|
@@ -128,11 +128,11 @@ class HandshakeResponse {
|
|
|
128
128
|
const p = this.serializeResponse(Packet.MockBuffer());
|
|
129
129
|
return this.serializeResponse(Buffer.alloc(p.offset));
|
|
130
130
|
}
|
|
131
|
-
static fromPacket(packet) {
|
|
131
|
+
static fromPacket(packet, serverFlags = 0xffffffff) {
|
|
132
132
|
const args = {};
|
|
133
133
|
args.clientFlags = packet.readInt32();
|
|
134
134
|
function isSet(flag) {
|
|
135
|
-
return args.clientFlags & ClientConstants[flag];
|
|
135
|
+
return args.clientFlags & serverFlags & ClientConstants[flag];
|
|
136
136
|
}
|
|
137
137
|
args.maxPacketSize = packet.readInt32();
|
|
138
138
|
args.charsetNumber = packet.readInt8();
|
package/lib/packets/packet.js
CHANGED
|
@@ -155,21 +155,17 @@ class Packet {
|
|
|
155
155
|
readInt64() {
|
|
156
156
|
const word0 = this.readInt32();
|
|
157
157
|
const word1 = this.readInt32();
|
|
158
|
-
|
|
158
|
+
const res = new Long(word0, word1, true);
|
|
159
159
|
const resNumber = res.toNumber();
|
|
160
|
-
|
|
161
|
-
res = resNumber.toString() === resString ? resNumber : resString;
|
|
162
|
-
return res;
|
|
160
|
+
return Number.isSafeInteger(resNumber) ? resNumber : res.toString();
|
|
163
161
|
}
|
|
164
162
|
|
|
165
163
|
readSInt64() {
|
|
166
164
|
const word0 = this.readInt32();
|
|
167
165
|
const word1 = this.readInt32();
|
|
168
|
-
|
|
166
|
+
const res = new Long(word0, word1, false);
|
|
169
167
|
const resNumber = res.toNumber();
|
|
170
|
-
|
|
171
|
-
res = resNumber.toString() === resString ? resNumber : resString;
|
|
172
|
-
return res;
|
|
168
|
+
return Number.isSafeInteger(resNumber) ? resNumber : res.toString();
|
|
173
169
|
}
|
|
174
170
|
|
|
175
171
|
isEOF() {
|
|
@@ -223,8 +219,10 @@ class Packet {
|
|
|
223
219
|
res = new Long(word0, word1, !signed); // Long need unsigned
|
|
224
220
|
const resNumber = res.toNumber();
|
|
225
221
|
const resString = res.toString();
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
if (bigNumberStrings || !Number.isSafeInteger(resNumber)) {
|
|
223
|
+
return resString;
|
|
224
|
+
}
|
|
225
|
+
return resNumber;
|
|
228
226
|
}
|
|
229
227
|
|
|
230
228
|
console.trace();
|
|
@@ -458,7 +456,7 @@ class Packet {
|
|
|
458
456
|
if (numDigits >= 15) {
|
|
459
457
|
str = this.readString(end - this.offset, 'binary');
|
|
460
458
|
result = parseInt(str, 10);
|
|
461
|
-
if (
|
|
459
|
+
if (Number.isSafeInteger(sign * result)) {
|
|
462
460
|
return sign * result;
|
|
463
461
|
}
|
|
464
462
|
return sign === -1 ? `-${str}` : str;
|
|
@@ -480,11 +478,10 @@ class Packet {
|
|
|
480
478
|
if (!supportBigNumbers) {
|
|
481
479
|
return num;
|
|
482
480
|
}
|
|
483
|
-
|
|
484
|
-
if (num.toString() === str) {
|
|
481
|
+
if (Number.isSafeInteger(num)) {
|
|
485
482
|
return num;
|
|
486
483
|
}
|
|
487
|
-
return
|
|
484
|
+
return this.buffer.toString('ascii', start, end);
|
|
488
485
|
}
|
|
489
486
|
|
|
490
487
|
// note that if value of inputNumberAsString is bigger than MAX_SAFE_INTEGER
|
package/lib/packets/query.js
CHANGED
|
@@ -4,24 +4,99 @@ const Packet = require('../packets/packet.js');
|
|
|
4
4
|
const CommandCode = require('../constants/commands.js');
|
|
5
5
|
const StringParser = require('../parsers/string.js');
|
|
6
6
|
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
|
7
|
+
const ClientConstants = require('../constants/client.js');
|
|
8
|
+
const Types = require('../constants/types.js');
|
|
9
|
+
const { toParameter } = require('./encode_parameter.js');
|
|
7
10
|
|
|
8
11
|
class Query {
|
|
9
|
-
constructor(sql, charsetNumber) {
|
|
12
|
+
constructor(sql, charsetNumber, attributes, clientFlags) {
|
|
10
13
|
this.query = sql;
|
|
11
14
|
this.charsetNumber = charsetNumber;
|
|
12
15
|
this.encoding = CharsetToEncoding[charsetNumber];
|
|
16
|
+
this.attributes = attributes;
|
|
17
|
+
this.clientFlags = clientFlags || 0;
|
|
13
18
|
}
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const packet = new Packet(0, buffer, 0, length);
|
|
20
|
+
serializeToBuffer(buffer) {
|
|
21
|
+
const useQueryAttributes =
|
|
22
|
+
this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
|
|
23
|
+
const sqlBuf = StringParser.encode(this.query, this.encoding);
|
|
24
|
+
const packet = new Packet(0, buffer, 0, buffer.length);
|
|
20
25
|
packet.offset = 4;
|
|
21
26
|
packet.writeInt8(CommandCode.QUERY);
|
|
22
|
-
|
|
27
|
+
|
|
28
|
+
if (useQueryAttributes) {
|
|
29
|
+
const attrs = this.attributes;
|
|
30
|
+
const names = attrs ? Object.keys(attrs) : [];
|
|
31
|
+
const paramCount = names.length;
|
|
32
|
+
|
|
33
|
+
packet.writeLengthCodedNumber(paramCount);
|
|
34
|
+
packet.writeLengthCodedNumber(1); // parameter_set_count, always 1
|
|
35
|
+
|
|
36
|
+
if (paramCount > 0) {
|
|
37
|
+
const parameters = names.map((name) =>
|
|
38
|
+
toParameter(attrs[name], this.encoding, 'local')
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// null bitmap
|
|
42
|
+
let bitmap = 0;
|
|
43
|
+
let bitValue = 1;
|
|
44
|
+
parameters.forEach((parameter) => {
|
|
45
|
+
if (parameter.type === Types.NULL) {
|
|
46
|
+
bitmap += bitValue;
|
|
47
|
+
}
|
|
48
|
+
bitValue *= 2;
|
|
49
|
+
if (bitValue === 256) {
|
|
50
|
+
packet.writeInt8(bitmap);
|
|
51
|
+
bitmap = 0;
|
|
52
|
+
bitValue = 1;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (bitValue !== 1) {
|
|
56
|
+
packet.writeInt8(bitmap);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
packet.writeInt8(1); // new_params_bind_flag
|
|
60
|
+
|
|
61
|
+
// types and names
|
|
62
|
+
for (let i = 0; i < paramCount; i++) {
|
|
63
|
+
packet.writeInt8(parameters[i].type);
|
|
64
|
+
packet.writeInt8(0); // unsigned flag
|
|
65
|
+
packet.writeLengthCodedString(names[i], this.encoding);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// values
|
|
69
|
+
parameters.forEach((parameter) => {
|
|
70
|
+
if (parameter.type !== Types.NULL) {
|
|
71
|
+
parameter.writer.call(packet, parameter.value);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
packet.writeBuffer(sqlBuf);
|
|
23
78
|
return packet;
|
|
24
79
|
}
|
|
80
|
+
|
|
81
|
+
toPacket() {
|
|
82
|
+
const useQueryAttributes =
|
|
83
|
+
this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
|
|
84
|
+
|
|
85
|
+
if (!useQueryAttributes) {
|
|
86
|
+
const buf = StringParser.encode(this.query, this.encoding);
|
|
87
|
+
const length = 5 + buf.length;
|
|
88
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
89
|
+
const packet = new Packet(0, buffer, 0, length);
|
|
90
|
+
packet.offset = 4;
|
|
91
|
+
packet.writeInt8(CommandCode.QUERY);
|
|
92
|
+
packet.writeBuffer(buf);
|
|
93
|
+
return packet;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// dry run to calculate required buffer length
|
|
97
|
+
const p = this.serializeToBuffer(Packet.MockBuffer());
|
|
98
|
+
return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
|
|
99
|
+
}
|
|
25
100
|
}
|
|
26
101
|
|
|
27
102
|
module.exports = Query;
|
|
@@ -39,7 +39,7 @@ class ResultSetHeader {
|
|
|
39
39
|
if (isSet('SESSION_TRACK') && packet.offset < packet.end) {
|
|
40
40
|
this.info = packet.readLengthCodedString(encoding);
|
|
41
41
|
|
|
42
|
-
if (this.serverStatus
|
|
42
|
+
if (this.serverStatus & ServerSatusFlags.SERVER_SESSION_STATE_CHANGED) {
|
|
43
43
|
// session change info record - see
|
|
44
44
|
// https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html#cs-sect-packet-ok-sessioninfo
|
|
45
45
|
let len =
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/mysql2",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.21.1-depup.0",
|
|
4
|
+
"description": "fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS (with updated dependencies)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "typings/mysql/index",
|
|
7
7
|
"type": "commonjs",
|
|
@@ -29,10 +29,12 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://sidorares.github.io/node-mysql2/docs",
|
|
31
31
|
"keywords": [
|
|
32
|
-
"depup",
|
|
33
|
-
"dependency-bumped",
|
|
34
|
-
"updated-deps",
|
|
35
32
|
"mysql2",
|
|
33
|
+
"depup",
|
|
34
|
+
"updated-dependencies",
|
|
35
|
+
"security",
|
|
36
|
+
"latest",
|
|
37
|
+
"patched",
|
|
36
38
|
"mysql",
|
|
37
39
|
"client",
|
|
38
40
|
"server"
|
|
@@ -43,7 +45,9 @@
|
|
|
43
45
|
"index.js",
|
|
44
46
|
"index.d.ts",
|
|
45
47
|
"promise.js",
|
|
46
|
-
"promise.d.ts"
|
|
48
|
+
"promise.d.ts",
|
|
49
|
+
"changes.json",
|
|
50
|
+
"README.md"
|
|
47
51
|
],
|
|
48
52
|
"exports": {
|
|
49
53
|
".": "./index.js",
|
|
@@ -100,8 +104,8 @@
|
|
|
100
104
|
"changes": {},
|
|
101
105
|
"depsUpdated": 0,
|
|
102
106
|
"originalPackage": "mysql2",
|
|
103
|
-
"originalVersion": "3.
|
|
104
|
-
"processedAt": "2026-
|
|
107
|
+
"originalVersion": "3.21.1",
|
|
108
|
+
"processedAt": "2026-04-10T05:04:49.223Z",
|
|
105
109
|
"smokeTest": "passed"
|
|
106
110
|
}
|
|
107
111
|
}
|
package/typings/mysql/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
Query as BaseQuery,
|
|
9
9
|
QueryOptions,
|
|
10
10
|
QueryError,
|
|
11
|
+
ExecuteValues,
|
|
12
|
+
QueryValues,
|
|
11
13
|
} from './lib/protocol/sequences/Query.js';
|
|
12
14
|
import {
|
|
13
15
|
PoolCluster as BasePoolCluster,
|
|
@@ -35,6 +37,8 @@ export {
|
|
|
35
37
|
PoolNamespace,
|
|
36
38
|
QueryOptions,
|
|
37
39
|
QueryError,
|
|
40
|
+
ExecuteValues,
|
|
41
|
+
QueryValues,
|
|
38
42
|
PrepareStatementInfo,
|
|
39
43
|
};
|
|
40
44
|
|
|
@@ -43,6 +43,13 @@ export interface QueryOptions {
|
|
|
43
43
|
*/
|
|
44
44
|
values?: QueryValues;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Query attributes sent alongside the query (MySQL 8.0.25+).
|
|
48
|
+
* Requires the `component_query_attributes` server component to be read via
|
|
49
|
+
* `mysql_query_attribute_string()`.
|
|
50
|
+
*/
|
|
51
|
+
attributes?: Record<string, string | number | boolean | null | Buffer | Date>;
|
|
52
|
+
|
|
46
53
|
/**
|
|
47
54
|
* This overrides the namedPlaceholders option set at the connection level.
|
|
48
55
|
*/
|