@depup/mysql2 3.23.4-depup.0 → 3.24.0-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 +1 -1
- package/index.js +5 -0
- package/lib/base/connection.js +3 -1
- package/lib/commands/execute.js +4 -1
- package/lib/commands/query.js +8 -8
- package/lib/compressed_protocol.js +5 -2
- package/lib/constants/types.js +1 -0
- package/lib/packet_parser.js +20 -16
- package/lib/packets/column_definition.js +11 -10
- package/lib/packets/encode_parameter.js +37 -7
- package/lib/packets/execute.js +74 -34
- package/lib/packets/packet.js +150 -20
- package/lib/packets/query.js +102 -66
- package/lib/packets/typed_parameter.js +381 -0
- package/lib/parsers/binary_parser.js +2 -2
- package/lib/parsers/parser_cache.js +21 -15
- package/lib/parsers/string.js +41 -0
- package/lib/promise/connection.js +6 -2
- package/lib/promise/pool.js +6 -2
- package/package.json +3 -3
- package/promise.js +5 -0
- package/typings/mysql/index.d.ts +1 -0
- package/typings/mysql/lib/TypedParameter.d.ts +84 -0
- package/typings/mysql/lib/protocol/sequences/Query.d.ts +2 -0
package/lib/packets/packet.js
CHANGED
|
@@ -10,7 +10,7 @@ const NativeBuffer = require('buffer').Buffer;
|
|
|
10
10
|
const Long = require('long');
|
|
11
11
|
const StringParser = require('../parsers/string.js');
|
|
12
12
|
const Types = require('../constants/types.js');
|
|
13
|
-
const
|
|
13
|
+
const ZERO_DATE = '0000-00-00';
|
|
14
14
|
|
|
15
15
|
// this is nearly duplicate of previous function so generated code is not slower
|
|
16
16
|
// due to "if (dateStrings)" branching
|
|
@@ -70,6 +70,27 @@ function jsonBigNumberReviver(key, value, context) {
|
|
|
70
70
|
const dot = '.'.charCodeAt(0);
|
|
71
71
|
const exponent = 'e'.charCodeAt(0);
|
|
72
72
|
const exponentCapital = 'E'.charCodeAt(0);
|
|
73
|
+
const colon = ':'.charCodeAt(0);
|
|
74
|
+
|
|
75
|
+
// '+HH:MM' / '-HH:MM' -> signed minutes, memoized on the last seen value
|
|
76
|
+
// (the timezone is a per-connection constant in practice)
|
|
77
|
+
let lastTimezone;
|
|
78
|
+
let lastTimezoneOffset = null;
|
|
79
|
+
function timezoneOffsetMinutes(timezone) {
|
|
80
|
+
if (timezone === lastTimezone) {
|
|
81
|
+
return lastTimezoneOffset;
|
|
82
|
+
}
|
|
83
|
+
let offset = null;
|
|
84
|
+
if (/^[+-]\d{2}:\d{2}$/.test(timezone)) {
|
|
85
|
+
offset =
|
|
86
|
+
(timezone[0] === '-' ? -1 : 1) *
|
|
87
|
+
(parseInt(timezone.substring(1, 3), 10) * 60 +
|
|
88
|
+
parseInt(timezone.substring(4), 10));
|
|
89
|
+
}
|
|
90
|
+
lastTimezone = timezone;
|
|
91
|
+
lastTimezoneOffset = offset;
|
|
92
|
+
return offset;
|
|
93
|
+
}
|
|
73
94
|
|
|
74
95
|
class Packet {
|
|
75
96
|
constructor(id, buffer, start, end) {
|
|
@@ -151,18 +172,14 @@ class Packet {
|
|
|
151
172
|
readInt64JSNumber() {
|
|
152
173
|
const word0 = this.readInt32();
|
|
153
174
|
const word1 = this.readInt32();
|
|
154
|
-
|
|
155
|
-
return
|
|
175
|
+
// same value Long.toNumber() would produce, without the allocation
|
|
176
|
+
return word0 + 0x100000000 * word1;
|
|
156
177
|
}
|
|
157
178
|
|
|
158
179
|
readSInt64JSNumber() {
|
|
159
180
|
const word0 = this.readInt32();
|
|
160
181
|
const word1 = this.readInt32();
|
|
161
|
-
|
|
162
|
-
return word0 + 0x100000000 * word1;
|
|
163
|
-
}
|
|
164
|
-
const l = new Long(word0, word1, false);
|
|
165
|
-
return l.toNumber();
|
|
182
|
+
return word0 + 0x100000000 * (word1 | 0);
|
|
166
183
|
}
|
|
167
184
|
|
|
168
185
|
readInt64String() {
|
|
@@ -182,17 +199,21 @@ class Packet {
|
|
|
182
199
|
readInt64() {
|
|
183
200
|
const word0 = this.readInt32();
|
|
184
201
|
const word1 = this.readInt32();
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
202
|
+
const resNumber = word0 + 0x100000000 * word1;
|
|
203
|
+
if (Number.isSafeInteger(resNumber)) {
|
|
204
|
+
return resNumber;
|
|
205
|
+
}
|
|
206
|
+
return new Long(word0, word1, true).toString();
|
|
188
207
|
}
|
|
189
208
|
|
|
190
209
|
readSInt64() {
|
|
191
210
|
const word0 = this.readInt32();
|
|
192
211
|
const word1 = this.readInt32();
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
212
|
+
const resNumber = word0 + 0x100000000 * (word1 | 0);
|
|
213
|
+
if (Number.isSafeInteger(resNumber)) {
|
|
214
|
+
return resNumber;
|
|
215
|
+
}
|
|
216
|
+
return new Long(word0, word1, false).toString();
|
|
196
217
|
}
|
|
197
218
|
|
|
198
219
|
isEOF() {
|
|
@@ -309,7 +330,7 @@ class Packet {
|
|
|
309
330
|
// possible MySQL flavours we still need to account for the
|
|
310
331
|
// non-standard behaviour.
|
|
311
332
|
if (y + m + d + H + M + S + ms === 0) {
|
|
312
|
-
return
|
|
333
|
+
return new Date(NaN);
|
|
313
334
|
}
|
|
314
335
|
if (timezone === 'Z') {
|
|
315
336
|
return new Date(Date.UTC(y, m - 1, d, H, M, S, ms));
|
|
@@ -317,8 +338,10 @@ class Packet {
|
|
|
317
338
|
return new Date(y, m - 1, d, H, M, S, ms);
|
|
318
339
|
}
|
|
319
340
|
let str = this.readDateTimeString(6, 'T', null);
|
|
320
|
-
if (
|
|
321
|
-
|
|
341
|
+
if (str.startsWith(ZERO_DATE)) {
|
|
342
|
+
// fresh instance: Date is mutable, a shared invalid-date singleton
|
|
343
|
+
// could be corrupted by callers (see the parseDateTime tests)
|
|
344
|
+
return new Date(NaN);
|
|
322
345
|
}
|
|
323
346
|
if (str.length === 10) {
|
|
324
347
|
str += 'T00:00:00';
|
|
@@ -335,7 +358,7 @@ class Packet {
|
|
|
335
358
|
let M = 0;
|
|
336
359
|
let S = 0;
|
|
337
360
|
let ms = 0;
|
|
338
|
-
let str;
|
|
361
|
+
let str = ZERO_DATE;
|
|
339
362
|
if (length > 3) {
|
|
340
363
|
y = this.readInt16();
|
|
341
364
|
m = this.readInt8();
|
|
@@ -723,10 +746,75 @@ class Packet {
|
|
|
723
746
|
}
|
|
724
747
|
|
|
725
748
|
parseDateTime(timezone) {
|
|
726
|
-
const
|
|
727
|
-
if (
|
|
749
|
+
const len = this.readLengthCodedNumber();
|
|
750
|
+
if (len === null) {
|
|
728
751
|
return null;
|
|
729
752
|
}
|
|
753
|
+
const b = this.buffer;
|
|
754
|
+
const s = this.offset;
|
|
755
|
+
// fast path for the wire format 'YYYY-MM-DD[ HH:MM:SS[.ffffff]]';
|
|
756
|
+
// parses digits straight from the buffer, avoiding both the intermediate
|
|
757
|
+
// string and the much slower Date-from-string constructor
|
|
758
|
+
if (
|
|
759
|
+
len >= 19 &&
|
|
760
|
+
b[s + 4] === minus &&
|
|
761
|
+
b[s + 7] === minus &&
|
|
762
|
+
b[s + 13] === colon &&
|
|
763
|
+
b[s + 16] === colon
|
|
764
|
+
) {
|
|
765
|
+
const y =
|
|
766
|
+
(b[s] - 48) * 1000 +
|
|
767
|
+
(b[s + 1] - 48) * 100 +
|
|
768
|
+
(b[s + 2] - 48) * 10 +
|
|
769
|
+
(b[s + 3] - 48);
|
|
770
|
+
const mo = (b[s + 5] - 48) * 10 + (b[s + 6] - 48);
|
|
771
|
+
const d = (b[s + 8] - 48) * 10 + (b[s + 9] - 48);
|
|
772
|
+
if (mo === 0 || d === 0 || mo > 12 || d > 31) {
|
|
773
|
+
// matches Date-from-string behaviour for zero/invalid dates
|
|
774
|
+
this.offset += len;
|
|
775
|
+
return new Date(NaN);
|
|
776
|
+
}
|
|
777
|
+
if (y < 100) {
|
|
778
|
+
// new Date(y, ...) maps years 0-99 to 1900+y; let the string
|
|
779
|
+
// constructor handle this (out of MySQL's documented range anyway)
|
|
780
|
+
const str = StringParser.decode(b, 'binary', s, s + len);
|
|
781
|
+
this.offset += len;
|
|
782
|
+
return !timezone || timezone === 'local'
|
|
783
|
+
? new Date(str)
|
|
784
|
+
: new Date(`${str}${timezone}`);
|
|
785
|
+
}
|
|
786
|
+
const h = (b[s + 11] - 48) * 10 + (b[s + 12] - 48);
|
|
787
|
+
const mi = (b[s + 14] - 48) * 10 + (b[s + 15] - 48);
|
|
788
|
+
const se = (b[s + 17] - 48) * 10 + (b[s + 18] - 48);
|
|
789
|
+
let ms = 0;
|
|
790
|
+
if (len > 20) {
|
|
791
|
+
// fractional part: Date resolution is ms, use the first 3 digits
|
|
792
|
+
let scale = 100;
|
|
793
|
+
for (let i = s + 20; i < s + len && scale >= 1; i++) {
|
|
794
|
+
ms += (b[i] - 48) * scale;
|
|
795
|
+
scale /= 10;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
this.offset += len;
|
|
799
|
+
if (!timezone || timezone === 'local') {
|
|
800
|
+
return new Date(y, mo - 1, d, h, mi, se, ms);
|
|
801
|
+
}
|
|
802
|
+
const utc = Date.UTC(y, mo - 1, d, h, mi, se, ms);
|
|
803
|
+
if (timezone === 'Z') {
|
|
804
|
+
return new Date(utc);
|
|
805
|
+
}
|
|
806
|
+
const offsetMinutes = timezoneOffsetMinutes(timezone);
|
|
807
|
+
if (offsetMinutes !== null) {
|
|
808
|
+
return new Date(utc - offsetMinutes * 60000);
|
|
809
|
+
}
|
|
810
|
+
// not a fixed '+HH:MM' offset: preserve the legacy string behaviour
|
|
811
|
+
// (V8 accepts some timezone abbreviations in Date-from-string)
|
|
812
|
+
return new Date(
|
|
813
|
+
`${StringParser.decode(b, 'binary', s, s + len)}${timezone}`
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
const str = StringParser.decode(b, 'binary', s, s + len);
|
|
817
|
+
this.offset += len;
|
|
730
818
|
if (!timezone || timezone === 'local') {
|
|
731
819
|
return new Date(str);
|
|
732
820
|
}
|
|
@@ -863,6 +951,44 @@ class Packet {
|
|
|
863
951
|
this.offset += 8;
|
|
864
952
|
}
|
|
865
953
|
|
|
954
|
+
writeFloat(n) {
|
|
955
|
+
this.buffer.writeFloatLE(n, this.offset);
|
|
956
|
+
this.offset += 4;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
writeUIntLE(n, bytes) {
|
|
960
|
+
if (bytes === 8) {
|
|
961
|
+
this.buffer.writeBigUInt64LE(n, this.offset);
|
|
962
|
+
} else {
|
|
963
|
+
this.buffer.writeUIntLE(Number(n), this.offset, bytes);
|
|
964
|
+
}
|
|
965
|
+
this.offset += bytes;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// must match writeTime's choice of encoding byte for byte
|
|
969
|
+
static timeLength({ days, hours, minutes, seconds, microseconds }) {
|
|
970
|
+
if (!days && !hours && !minutes && !seconds && !microseconds) {
|
|
971
|
+
return 1;
|
|
972
|
+
}
|
|
973
|
+
return microseconds ? 13 : 9;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
writeTime({ negative, days, hours, minutes, seconds, microseconds }) {
|
|
977
|
+
if (!days && !hours && !minutes && !seconds && !microseconds) {
|
|
978
|
+
this.writeInt8(0);
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
this.writeInt8(microseconds ? 12 : 8);
|
|
982
|
+
this.writeInt8(negative ? 1 : 0);
|
|
983
|
+
this.writeInt32(days);
|
|
984
|
+
this.writeInt8(hours);
|
|
985
|
+
this.writeInt8(minutes);
|
|
986
|
+
this.writeInt8(seconds);
|
|
987
|
+
if (microseconds) {
|
|
988
|
+
this.writeInt32(microseconds);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
866
992
|
writeBuffer(b) {
|
|
867
993
|
b.copy(this.buffer, this.offset);
|
|
868
994
|
this.offset += b.length;
|
|
@@ -1009,6 +1135,9 @@ class Packet {
|
|
|
1009
1135
|
}
|
|
1010
1136
|
|
|
1011
1137
|
static MockBuffer() {
|
|
1138
|
+
if (Packet._mockBuffer) {
|
|
1139
|
+
return Packet._mockBuffer;
|
|
1140
|
+
}
|
|
1012
1141
|
const noop = function () {};
|
|
1013
1142
|
const res = Buffer.alloc(0);
|
|
1014
1143
|
for (const op in NativeBuffer.prototype) {
|
|
@@ -1016,6 +1145,7 @@ class Packet {
|
|
|
1016
1145
|
res[op] = noop;
|
|
1017
1146
|
}
|
|
1018
1147
|
}
|
|
1148
|
+
Packet._mockBuffer = res;
|
|
1019
1149
|
return res;
|
|
1020
1150
|
}
|
|
1021
1151
|
}
|
package/lib/packets/query.js
CHANGED
|
@@ -5,7 +5,6 @@ const CommandCode = require('../constants/commands.js');
|
|
|
5
5
|
const StringParser = require('../parsers/string.js');
|
|
6
6
|
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
|
7
7
|
const ClientConstants = require('../constants/client.js');
|
|
8
|
-
const Types = require('../constants/types.js');
|
|
9
8
|
const { toParameter } = require('./encode_parameter.js');
|
|
10
9
|
|
|
11
10
|
class Query {
|
|
@@ -17,85 +16,122 @@ class Query {
|
|
|
17
16
|
this.clientFlags = clientFlags || 0;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
toPacket() {
|
|
21
20
|
const useQueryAttributes =
|
|
22
21
|
this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
);
|
|
22
|
+
const attributeCount =
|
|
23
|
+
useQueryAttributes && this.attributes
|
|
24
|
+
? Object.keys(this.attributes).length
|
|
25
|
+
: 0;
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (bitValue !== 1) {
|
|
56
|
-
packet.writeInt8(bitmap);
|
|
27
|
+
if (attributeCount === 0) {
|
|
28
|
+
// fast path: no attribute values to serialize, so the packet length is
|
|
29
|
+
// known upfront and the SQL can be encoded straight into the buffer
|
|
30
|
+
const headerLength = useQueryAttributes ? 7 : 5;
|
|
31
|
+
if (Buffer.isEncoding(this.encoding)) {
|
|
32
|
+
const sqlLength = Buffer.byteLength(this.query, this.encoding);
|
|
33
|
+
const length = headerLength + sqlLength;
|
|
34
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
35
|
+
const packet = new Packet(0, buffer, 0, length);
|
|
36
|
+
packet.offset = 4;
|
|
37
|
+
packet.writeInt8(CommandCode.QUERY);
|
|
38
|
+
if (useQueryAttributes) {
|
|
39
|
+
packet.writeInt8(0); // parameter_count
|
|
40
|
+
packet.writeInt8(1); // parameter_set_count, always 1
|
|
57
41
|
}
|
|
58
|
-
|
|
59
|
-
packet.
|
|
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
|
-
});
|
|
42
|
+
buffer.write(this.query, packet.offset, this.encoding);
|
|
43
|
+
packet.offset = length;
|
|
44
|
+
return packet;
|
|
74
45
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
packet.writeBuffer(sqlBuf);
|
|
78
|
-
return packet;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
toPacket() {
|
|
82
|
-
const useQueryAttributes =
|
|
83
|
-
this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
|
|
84
|
-
|
|
85
|
-
if (!useQueryAttributes) {
|
|
86
46
|
const buf = StringParser.encode(this.query, this.encoding);
|
|
87
|
-
const length =
|
|
47
|
+
const length = headerLength + buf.length;
|
|
88
48
|
const buffer = Buffer.allocUnsafe(length);
|
|
89
49
|
const packet = new Packet(0, buffer, 0, length);
|
|
90
50
|
packet.offset = 4;
|
|
91
51
|
packet.writeInt8(CommandCode.QUERY);
|
|
52
|
+
if (useQueryAttributes) {
|
|
53
|
+
packet.writeInt8(0); // parameter_count
|
|
54
|
+
packet.writeInt8(1); // parameter_set_count, always 1
|
|
55
|
+
}
|
|
92
56
|
packet.writeBuffer(buf);
|
|
93
57
|
return packet;
|
|
94
58
|
}
|
|
95
59
|
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
60
|
+
const names = Object.keys(this.attributes);
|
|
61
|
+
const parameters = new Array(attributeCount);
|
|
62
|
+
const nameBuffers = new Array(attributeCount);
|
|
63
|
+
|
|
64
|
+
// packet header, command, parameter count, parameter_set_count (always
|
|
65
|
+
// the single-byte form), null bitmap, new_params_bind_flag, type and
|
|
66
|
+
// unsigned byte per parameter
|
|
67
|
+
let length =
|
|
68
|
+
5 +
|
|
69
|
+
Packet.lengthCodedNumberLength(attributeCount) +
|
|
70
|
+
1 +
|
|
71
|
+
((attributeCount + 7) >> 3) +
|
|
72
|
+
1 +
|
|
73
|
+
attributeCount * 2;
|
|
74
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
75
|
+
parameters[i] = toParameter(
|
|
76
|
+
this.attributes[names[i]],
|
|
77
|
+
this.encoding,
|
|
78
|
+
'local'
|
|
79
|
+
);
|
|
80
|
+
const name = StringParser.encode(names[i], this.encoding);
|
|
81
|
+
nameBuffers[i] = name;
|
|
82
|
+
length += Packet.lengthCodedNumberLength(name.length) + name.length;
|
|
83
|
+
if (!parameters[i].isNull) {
|
|
84
|
+
length += parameters[i].length;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const sqlBuffer = StringParser.encode(this.query, this.encoding);
|
|
88
|
+
length += sqlBuffer.length;
|
|
89
|
+
|
|
90
|
+
const packet = new Packet(0, Buffer.allocUnsafe(length), 0, length);
|
|
91
|
+
packet.offset = 4;
|
|
92
|
+
packet.writeInt8(CommandCode.QUERY);
|
|
93
|
+
packet.writeLengthCodedNumber(attributeCount);
|
|
94
|
+
packet.writeLengthCodedNumber(1); // parameter_set_count, always 1
|
|
95
|
+
|
|
96
|
+
let bitmap = 0;
|
|
97
|
+
let bitValue = 1;
|
|
98
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
99
|
+
if (parameters[i].isNull) {
|
|
100
|
+
bitmap |= bitValue;
|
|
101
|
+
}
|
|
102
|
+
bitValue *= 2;
|
|
103
|
+
if (bitValue === 256) {
|
|
104
|
+
packet.writeInt8(bitmap);
|
|
105
|
+
bitmap = 0;
|
|
106
|
+
bitValue = 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (bitValue !== 1) {
|
|
110
|
+
packet.writeInt8(bitmap);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
packet.writeInt8(1); // new_params_bind_flag
|
|
114
|
+
|
|
115
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
116
|
+
packet.writeInt8(parameters[i].type);
|
|
117
|
+
packet.writeInt8(parameters[i].unsigned ? 0x80 : 0);
|
|
118
|
+
packet.writeLengthCodedBuffer(nameBuffers[i]);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
for (let i = 0; i < attributeCount; i++) {
|
|
122
|
+
if (!parameters[i].isNull) {
|
|
123
|
+
parameters[i].writer.call(packet, parameters[i].value);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
packet.writeBuffer(sqlBuffer);
|
|
128
|
+
|
|
129
|
+
if (packet.offset !== length) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Internal error: COM_QUERY serialized ${packet.offset - 4} bytes, expected ${length - 4}`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return packet;
|
|
99
135
|
}
|
|
100
136
|
}
|
|
101
137
|
|