mysql2 3.24.0 → 3.24.1
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/lib/packets/encode_parameter.js +16 -2
- package/lib/packets/execute.js +1 -1
- package/lib/packets/packet.js +12 -0
- package/lib/packets/prepare_statement.js +12 -0
- package/lib/packets/query.js +37 -26
- package/lib/packets/typed_parameter.js +18 -8
- package/lib/parsers/string.js +4 -0
- package/package.json +1 -1
|
@@ -88,14 +88,28 @@ function toParameter(value, encoding, timezone, jsonAsString, hint) {
|
|
|
88
88
|
length = 0;
|
|
89
89
|
writer = writeNothing;
|
|
90
90
|
}
|
|
91
|
+
let byteLength;
|
|
91
92
|
if (length === undefined) {
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
// a non-string here (e.g. a Uint8Array) keeps the Buffer.from coercion
|
|
94
|
+
// inside StringParser.encode
|
|
95
|
+
if (
|
|
96
|
+
typeof value === 'string' &&
|
|
97
|
+
StringParser.hasFastUtf8Write &&
|
|
98
|
+
(encoding === 'utf8' || encoding === 'utf-8')
|
|
99
|
+
) {
|
|
100
|
+
byteLength = Buffer.byteLength(value, 'utf8');
|
|
101
|
+
length = Packet.lengthCodedNumberLength(byteLength) + byteLength;
|
|
102
|
+
writer = Packet.prototype.writeLengthCodedUtf8String;
|
|
103
|
+
} else {
|
|
104
|
+
value = StringParser.encode(value, encoding);
|
|
105
|
+
length = Packet.lengthCodedNumberLength(value.length) + value.length;
|
|
106
|
+
}
|
|
94
107
|
}
|
|
95
108
|
return {
|
|
96
109
|
value,
|
|
97
110
|
type,
|
|
98
111
|
length,
|
|
112
|
+
byteLength,
|
|
99
113
|
writer,
|
|
100
114
|
unsigned: false,
|
|
101
115
|
isNull: type === Types.NULL,
|
package/lib/packets/execute.js
CHANGED
|
@@ -206,7 +206,7 @@ class Execute {
|
|
|
206
206
|
for (let i = 0; i < totalParams; i++) {
|
|
207
207
|
const parameter = allParams[i];
|
|
208
208
|
if (!parameter.isNull) {
|
|
209
|
-
parameter.writer.call(packet, parameter.value);
|
|
209
|
+
parameter.writer.call(packet, parameter.value, parameter.byteLength);
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
}
|
package/lib/packets/packet.js
CHANGED
|
@@ -1030,6 +1030,18 @@ class Packet {
|
|
|
1030
1030
|
this.offset += buf.length;
|
|
1031
1031
|
}
|
|
1032
1032
|
|
|
1033
|
+
// byteLength, when the caller sized the packet, must be
|
|
1034
|
+
// Buffer.byteLength(string, 'utf8'); only used where
|
|
1035
|
+
// Buffer.prototype.utf8Write exists
|
|
1036
|
+
writeLengthCodedUtf8String(string, byteLength) {
|
|
1037
|
+
if (byteLength === undefined) {
|
|
1038
|
+
byteLength = Buffer.byteLength(string, 'utf8');
|
|
1039
|
+
}
|
|
1040
|
+
this.writeLengthCodedNumber(byteLength);
|
|
1041
|
+
this.buffer.utf8Write(string, this.offset, byteLength);
|
|
1042
|
+
this.offset += byteLength;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1033
1045
|
writeLengthCodedBuffer(b) {
|
|
1034
1046
|
this.writeLengthCodedNumber(b.length);
|
|
1035
1047
|
b.copy(this.buffer, this.offset);
|
|
@@ -13,6 +13,18 @@ class PrepareStatement {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
toPacket() {
|
|
16
|
+
if (
|
|
17
|
+
StringParser.hasFastUtf8Write &&
|
|
18
|
+
(this.encoding === 'utf8' || this.encoding === 'utf-8')
|
|
19
|
+
) {
|
|
20
|
+
const length = 5 + Buffer.byteLength(this.query, 'utf8');
|
|
21
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
22
|
+
buffer[4] = CommandCodes.STMT_PREPARE;
|
|
23
|
+
buffer.utf8Write(this.query, 5, length - 5);
|
|
24
|
+
const packet = new Packet(0, buffer, 0, length);
|
|
25
|
+
packet.offset = length;
|
|
26
|
+
return packet;
|
|
27
|
+
}
|
|
16
28
|
const buf = StringParser.encode(this.query, this.encoding);
|
|
17
29
|
const length = 5 + buf.length;
|
|
18
30
|
const buffer = Buffer.allocUnsafe(length);
|
package/lib/packets/query.js
CHANGED
|
@@ -7,6 +7,19 @@ const CharsetToEncoding = require('../constants/charset_encodings.js');
|
|
|
7
7
|
const ClientConstants = require('../constants/client.js');
|
|
8
8
|
const { toParameter } = require('./encode_parameter.js');
|
|
9
9
|
|
|
10
|
+
const { hasFastUtf8Write } = StringParser;
|
|
11
|
+
|
|
12
|
+
function toQueryPacket(buffer, headerLength, length) {
|
|
13
|
+
buffer[4] = CommandCode.QUERY;
|
|
14
|
+
if (headerLength === 7) {
|
|
15
|
+
buffer[5] = 0; // parameter_count
|
|
16
|
+
buffer[6] = 1; // parameter_set_count, always 1
|
|
17
|
+
}
|
|
18
|
+
const packet = new Packet(0, buffer, 0, length);
|
|
19
|
+
packet.offset = length;
|
|
20
|
+
return packet;
|
|
21
|
+
}
|
|
22
|
+
|
|
10
23
|
class Query {
|
|
11
24
|
constructor(sql, charsetNumber, attributes, clientFlags) {
|
|
12
25
|
this.query = sql;
|
|
@@ -25,36 +38,30 @@ class Query {
|
|
|
25
38
|
: 0;
|
|
26
39
|
|
|
27
40
|
if (attributeCount === 0) {
|
|
28
|
-
// fast path: no attribute values to serialize, so the packet
|
|
29
|
-
//
|
|
41
|
+
// fast path: no attribute values to serialize, so the packet is the
|
|
42
|
+
// header plus the encoded SQL
|
|
30
43
|
const headerLength = useQueryAttributes ? 7 : 5;
|
|
44
|
+
if (
|
|
45
|
+
hasFastUtf8Write &&
|
|
46
|
+
(this.encoding === 'utf8' || this.encoding === 'utf-8')
|
|
47
|
+
) {
|
|
48
|
+
const length = headerLength + Buffer.byteLength(this.query, 'utf8');
|
|
49
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
50
|
+
buffer.utf8Write(this.query, headerLength, length - headerLength);
|
|
51
|
+
return toQueryPacket(buffer, headerLength, length);
|
|
52
|
+
}
|
|
31
53
|
if (Buffer.isEncoding(this.encoding)) {
|
|
32
|
-
const
|
|
33
|
-
|
|
54
|
+
const length =
|
|
55
|
+
headerLength + Buffer.byteLength(this.query, this.encoding);
|
|
34
56
|
const buffer = Buffer.allocUnsafe(length);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
packet.writeInt8(CommandCode.QUERY);
|
|
38
|
-
if (useQueryAttributes) {
|
|
39
|
-
packet.writeInt8(0); // parameter_count
|
|
40
|
-
packet.writeInt8(1); // parameter_set_count, always 1
|
|
41
|
-
}
|
|
42
|
-
buffer.write(this.query, packet.offset, this.encoding);
|
|
43
|
-
packet.offset = length;
|
|
44
|
-
return packet;
|
|
57
|
+
buffer.write(this.query, headerLength, this.encoding);
|
|
58
|
+
return toQueryPacket(buffer, headerLength, length);
|
|
45
59
|
}
|
|
46
|
-
const
|
|
47
|
-
const length = headerLength +
|
|
60
|
+
const sqlBuffer = StringParser.encode(this.query, this.encoding);
|
|
61
|
+
const length = headerLength + sqlBuffer.length;
|
|
48
62
|
const buffer = Buffer.allocUnsafe(length);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
packet.writeInt8(CommandCode.QUERY);
|
|
52
|
-
if (useQueryAttributes) {
|
|
53
|
-
packet.writeInt8(0); // parameter_count
|
|
54
|
-
packet.writeInt8(1); // parameter_set_count, always 1
|
|
55
|
-
}
|
|
56
|
-
packet.writeBuffer(buf);
|
|
57
|
-
return packet;
|
|
63
|
+
sqlBuffer.copy(buffer, headerLength);
|
|
64
|
+
return toQueryPacket(buffer, headerLength, length);
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
const names = Object.keys(this.attributes);
|
|
@@ -120,7 +127,11 @@ class Query {
|
|
|
120
127
|
|
|
121
128
|
for (let i = 0; i < attributeCount; i++) {
|
|
122
129
|
if (!parameters[i].isNull) {
|
|
123
|
-
parameters[i].writer.call(
|
|
130
|
+
parameters[i].writer.call(
|
|
131
|
+
packet,
|
|
132
|
+
parameters[i].value,
|
|
133
|
+
parameters[i].byteLength
|
|
134
|
+
);
|
|
124
135
|
}
|
|
125
136
|
}
|
|
126
137
|
|
|
@@ -238,15 +238,25 @@ function timeEncoder() {
|
|
|
238
238
|
|
|
239
239
|
function lengthCodedEncoder(encoding) {
|
|
240
240
|
return (value) => {
|
|
241
|
-
|
|
242
|
-
? value
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
241
|
+
if (!Buffer.isBuffer(value)) {
|
|
242
|
+
const string = typeof value === 'string' ? value : String(value);
|
|
243
|
+
if (
|
|
244
|
+
StringParser.hasFastUtf8Write &&
|
|
245
|
+
(encoding === 'utf8' || encoding === 'utf-8')
|
|
246
|
+
) {
|
|
247
|
+
const byteLength = Buffer.byteLength(string, 'utf8');
|
|
248
|
+
return {
|
|
249
|
+
value: string,
|
|
250
|
+
length: Packet.lengthCodedNumberLength(byteLength) + byteLength,
|
|
251
|
+
byteLength,
|
|
252
|
+
writer: Packet.prototype.writeLengthCodedUtf8String,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
value = StringParser.encode(string, encoding);
|
|
256
|
+
}
|
|
247
257
|
return {
|
|
248
|
-
value
|
|
249
|
-
length: Packet.lengthCodedNumberLength(
|
|
258
|
+
value,
|
|
259
|
+
length: Packet.lengthCodedNumberLength(value.length) + value.length,
|
|
250
260
|
writer: Packet.prototype.writeLengthCodedBuffer,
|
|
251
261
|
};
|
|
252
262
|
};
|
package/lib/parsers/string.js
CHANGED
|
@@ -15,6 +15,10 @@ const hasFastSlices =
|
|
|
15
15
|
typeof Buffer.prototype.latin1Slice === 'function' &&
|
|
16
16
|
typeof Buffer.prototype.asciiSlice === 'function';
|
|
17
17
|
|
|
18
|
+
// utf8Write skips the per-call encoding normalization and dispatch inside
|
|
19
|
+
// buffer.write(); same stability story as the slice methods above
|
|
20
|
+
exports.hasFastUtf8Write = typeof Buffer.prototype.utf8Write === 'function';
|
|
21
|
+
|
|
18
22
|
exports.decode = function (buffer, encoding, start, end, options) {
|
|
19
23
|
if (hasFastSlices) {
|
|
20
24
|
// replicate buffer.toString() bounds coercion exactly (the *Slice
|
package/package.json
CHANGED