@tachybase/module-multi-app 1.6.0 → 1.6.2
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 +34 -34
- package/README.zh-CN.md +34 -34
- package/client.d.ts +1 -1
- package/client.js +1 -1
- package/dist/externalVersion.js +5 -5
- package/dist/locale/en-US.json +48 -48
- package/dist/locale/es-ES.json +9 -9
- package/dist/locale/ko_KR.json +11 -11
- package/dist/locale/pt-BR.json +9 -9
- package/dist/locale/zh-CN.json +58 -58
- package/dist/node_modules/mariadb/callback.js +43 -8
- package/dist/node_modules/mariadb/check-node.js +30 -0
- package/dist/node_modules/mariadb/lib/cluster-callback.js +84 -0
- package/dist/node_modules/mariadb/lib/cluster.js +446 -0
- package/dist/node_modules/mariadb/lib/cmd/batch-bulk.js +576 -177
- package/dist/node_modules/mariadb/lib/cmd/change-user.js +54 -44
- package/dist/node_modules/mariadb/lib/cmd/class/ok-packet.js +3 -2
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-cache-wrapper.js +46 -0
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-result-packet.js +141 -0
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-wrapper.js +70 -0
- package/dist/node_modules/mariadb/lib/cmd/close-prepare.js +38 -0
- package/dist/node_modules/mariadb/lib/cmd/column-definition.js +145 -47
- package/dist/node_modules/mariadb/lib/cmd/command.js +41 -75
- package/dist/node_modules/mariadb/lib/cmd/decoder/binary-decoder.js +282 -0
- package/dist/node_modules/mariadb/lib/cmd/decoder/text-decoder.js +210 -0
- package/dist/node_modules/mariadb/lib/cmd/{common-binary-cmd.js → encoder/binary-encoder.js} +34 -77
- package/dist/node_modules/mariadb/lib/cmd/encoder/text-encoder.js +311 -0
- package/dist/node_modules/mariadb/lib/cmd/execute-stream.js +61 -0
- package/dist/node_modules/mariadb/lib/cmd/execute.js +338 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/caching-sha2-password-auth.js +25 -62
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/clear-password-auth.js +39 -6
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/ed25519-password-auth.js +48 -16
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/handshake.js +198 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/{initial-handshake.js → auth/initial-handshake.js} +10 -8
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/native-password-auth.js +22 -9
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/pam-password-auth.js +9 -4
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/parsec-auth.js +115 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/plugin-auth.js +12 -5
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/sha256-password-auth.js +44 -33
- package/dist/node_modules/mariadb/lib/cmd/handshake/authentication.js +335 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-capabilities.js +20 -19
- package/dist/node_modules/mariadb/lib/cmd/handshake/ssl-request.js +6 -3
- package/dist/node_modules/mariadb/lib/cmd/parser.js +861 -0
- package/dist/node_modules/mariadb/lib/cmd/ping.js +17 -18
- package/dist/node_modules/mariadb/lib/cmd/prepare.js +170 -0
- package/dist/node_modules/mariadb/lib/cmd/query.js +281 -144
- package/dist/node_modules/mariadb/lib/cmd/quit.js +9 -6
- package/dist/node_modules/mariadb/lib/cmd/reset.js +15 -19
- package/dist/node_modules/mariadb/lib/cmd/stream.js +21 -6
- package/dist/node_modules/mariadb/lib/config/cluster-options.js +23 -0
- package/dist/node_modules/mariadb/lib/config/connection-options.js +196 -132
- package/dist/node_modules/mariadb/lib/config/pool-options.js +27 -19
- package/dist/node_modules/mariadb/lib/connection-callback.js +492 -120
- package/dist/node_modules/mariadb/lib/connection-promise.js +372 -0
- package/dist/node_modules/mariadb/lib/connection.js +1739 -1016
- package/dist/node_modules/mariadb/lib/const/capabilities.js +36 -30
- package/dist/node_modules/mariadb/lib/const/collations.js +972 -36
- package/dist/node_modules/mariadb/lib/const/connection_status.js +3 -0
- package/dist/node_modules/mariadb/lib/const/error-code.js +35 -11
- package/dist/node_modules/mariadb/lib/const/field-detail.js +3 -0
- package/dist/node_modules/mariadb/lib/const/field-type.js +7 -4
- package/dist/node_modules/mariadb/lib/const/server-status.js +4 -1
- package/dist/node_modules/mariadb/lib/const/state-change.js +3 -0
- package/dist/node_modules/mariadb/lib/filtered-cluster-callback.js +136 -0
- package/dist/node_modules/mariadb/lib/filtered-cluster.js +118 -0
- package/dist/node_modules/mariadb/lib/io/compression-input-stream.js +14 -13
- package/dist/node_modules/mariadb/lib/io/compression-output-stream.js +21 -18
- package/dist/node_modules/mariadb/lib/io/packet-input-stream.js +75 -64
- package/dist/node_modules/mariadb/lib/io/packet-node-encoded.js +13 -9
- package/dist/node_modules/mariadb/lib/io/packet-node-iconv.js +12 -10
- package/dist/node_modules/mariadb/lib/io/packet-output-stream.js +402 -134
- package/dist/node_modules/mariadb/lib/io/packet.js +287 -202
- package/dist/node_modules/mariadb/lib/lru-prepare-cache.js +84 -0
- package/dist/node_modules/mariadb/lib/misc/connection-information.js +15 -32
- package/dist/node_modules/mariadb/lib/misc/errors.js +68 -25
- package/dist/node_modules/mariadb/lib/misc/parse.js +207 -711
- package/dist/node_modules/mariadb/lib/misc/utils.js +34 -62
- package/dist/node_modules/mariadb/lib/pool-callback.js +213 -174
- package/dist/node_modules/mariadb/lib/pool-promise.js +228 -94
- package/dist/node_modules/mariadb/lib/pool.js +951 -0
- package/dist/node_modules/mariadb/package.json +1 -1
- package/dist/node_modules/mariadb/promise.js +1 -34
- package/dist/node_modules/mariadb/types/callback.d.ts +207 -0
- package/dist/node_modules/mariadb/types/index.d.ts +94 -674
- package/dist/node_modules/mariadb/types/share.d.ts +804 -0
- package/dist/node_modules/qs/package.json +1 -1
- package/dist/server/actions/apps.js +2 -2
- package/dist/server/app-lifecycle.d.ts +1 -1
- package/dist/server/app-lifecycle.js +4 -4
- package/dist/server/models/application.d.ts +1 -1
- package/package.json +7 -7
- package/server.d.ts +2 -2
- package/server.js +1 -1
- package/dist/node_modules/mariadb/lib/cmd/batch-rewrite.js +0 -372
- package/dist/node_modules/mariadb/lib/cmd/common-text-cmd.js +0 -427
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-handshake-response.js +0 -126
- package/dist/node_modules/mariadb/lib/cmd/handshake/handshake.js +0 -292
- package/dist/node_modules/mariadb/lib/cmd/resultset.js +0 -607
- package/dist/node_modules/mariadb/lib/config/pool-cluster-options.js +0 -19
- package/dist/node_modules/mariadb/lib/filtered-pool-cluster.js +0 -81
- package/dist/node_modules/mariadb/lib/io/bulk-packet.js +0 -590
- package/dist/node_modules/mariadb/lib/io/rewrite-packet.js +0 -481
- package/dist/node_modules/mariadb/lib/pool-base.js +0 -611
- package/dist/node_modules/mariadb/lib/pool-cluster-callback.js +0 -66
- package/dist/node_modules/mariadb/lib/pool-cluster.js +0 -407
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2025 MariaDB Corporation Ab
|
|
3
|
+
|
|
1
4
|
'use strict';
|
|
2
5
|
|
|
3
6
|
const Iconv = require('iconv-lite');
|
|
4
7
|
const Utils = require('../misc/utils');
|
|
8
|
+
const Errors = require('../misc/errors');
|
|
9
|
+
const Collations = require('../const/collations');
|
|
5
10
|
|
|
6
11
|
const QUOTE = 0x27;
|
|
7
12
|
const DBL_QUOTE = 0x22;
|
|
@@ -9,12 +14,12 @@ const ZERO_BYTE = 0x00;
|
|
|
9
14
|
const SLASH = 0x5c;
|
|
10
15
|
|
|
11
16
|
//increase by level to avoid buffer copy.
|
|
12
|
-
const SMALL_BUFFER_SIZE =
|
|
17
|
+
const SMALL_BUFFER_SIZE = 256;
|
|
13
18
|
const MEDIUM_BUFFER_SIZE = 16384; //16k
|
|
14
19
|
const LARGE_BUFFER_SIZE = 131072; //128k
|
|
15
20
|
const BIG_BUFFER_SIZE = 1048576; //1M
|
|
16
21
|
const MAX_BUFFER_SIZE = 16777219; //16M + 4
|
|
17
|
-
const CHARS_GLOBAL_REGEXP = /[\
|
|
22
|
+
const CHARS_GLOBAL_REGEXP = /[\000\032"'\\\n\r\t]/g;
|
|
18
23
|
|
|
19
24
|
/**
|
|
20
25
|
* MySQL packet builder.
|
|
@@ -28,9 +33,15 @@ class PacketOutputStream {
|
|
|
28
33
|
this.opts = opts;
|
|
29
34
|
this.info = info;
|
|
30
35
|
this.pos = 4;
|
|
36
|
+
this.markPos = -1;
|
|
37
|
+
this.bufContainDataAfterMark = false;
|
|
38
|
+
this.cmdLength = 0;
|
|
31
39
|
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
40
|
+
this.maxAllowedPacket = opts.maxAllowedPacket || 16777216;
|
|
41
|
+
this.maxPacketLength = Math.min(MAX_BUFFER_SIZE, this.maxAllowedPacket + 4);
|
|
42
|
+
|
|
43
|
+
this.changeEncoding(this.opts.collation ? this.opts.collation : Collations.fromIndex(224));
|
|
44
|
+
this.changeDebug(this.opts.debug);
|
|
34
45
|
|
|
35
46
|
this.opts.on('collation', this.changeEncoding.bind(this));
|
|
36
47
|
this.opts.on('debug', this.changeDebug.bind(this));
|
|
@@ -40,21 +51,26 @@ class PacketOutputStream {
|
|
|
40
51
|
this.encoding = collation.charset;
|
|
41
52
|
if (this.encoding === 'utf8') {
|
|
42
53
|
this.writeString = this.writeDefaultBufferString;
|
|
54
|
+
this.encodeString = this.encodeNodeString;
|
|
55
|
+
this.writeLengthEncodedString = this.writeDefaultBufferLengthEncodedString;
|
|
43
56
|
this.writeStringEscapeQuote = this.writeUtf8StringEscapeQuote;
|
|
44
57
|
} else if (Buffer.isEncoding(this.encoding)) {
|
|
45
58
|
this.writeString = this.writeDefaultBufferString;
|
|
59
|
+
this.encodeString = this.encodeNodeString;
|
|
60
|
+
this.writeLengthEncodedString = this.writeDefaultBufferLengthEncodedString;
|
|
46
61
|
this.writeStringEscapeQuote = this.writeDefaultStringEscapeQuote;
|
|
47
62
|
} else {
|
|
48
63
|
this.writeString = this.writeDefaultIconvString;
|
|
64
|
+
this.encodeString = this.encodeIconvString;
|
|
65
|
+
this.writeLengthEncodedString = this.writeDefaultIconvLengthEncodedString;
|
|
49
66
|
this.writeStringEscapeQuote = this.writeDefaultStringEscapeQuote;
|
|
50
67
|
}
|
|
51
68
|
}
|
|
52
69
|
|
|
53
|
-
changeDebug(
|
|
54
|
-
this.logPackets = logPackets;
|
|
70
|
+
changeDebug(debug) {
|
|
55
71
|
this.debug = debug;
|
|
56
|
-
this.flushBuffer =
|
|
57
|
-
|
|
72
|
+
this.flushBuffer = debug ? this.flushBufferDebug : this.flushBufferBasic;
|
|
73
|
+
this.fastFlush = debug ? this.fastFlushDebug : this.fastFlushBasic;
|
|
58
74
|
}
|
|
59
75
|
|
|
60
76
|
setStream(stream) {
|
|
@@ -69,13 +85,92 @@ class PacketOutputStream {
|
|
|
69
85
|
newCapacity = LARGE_BUFFER_SIZE;
|
|
70
86
|
} else if (len + this.pos < BIG_BUFFER_SIZE) {
|
|
71
87
|
newCapacity = BIG_BUFFER_SIZE;
|
|
72
|
-
} else
|
|
88
|
+
} else if (this.bufContainDataAfterMark) {
|
|
89
|
+
// special case, for bulk, when a bunch of parameter doesn't fit in 16Mb packet
|
|
90
|
+
// this save bunch of encoded parameter, sending parameter until mark, then resending data after mark
|
|
91
|
+
newCapacity = len + this.pos;
|
|
92
|
+
} else {
|
|
93
|
+
newCapacity = MAX_BUFFER_SIZE;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (len + this.pos > newCapacity) {
|
|
97
|
+
if (this.markPos !== -1) {
|
|
98
|
+
// buf is > 16M with mark.
|
|
99
|
+
// flush until mark, reset pos at beginning
|
|
100
|
+
this.flushBufferStopAtMark();
|
|
101
|
+
|
|
102
|
+
if (len + this.pos <= this.buf.length) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
return this.growBuffer(len);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
73
108
|
|
|
74
109
|
let newBuf = Buffer.allocUnsafe(newCapacity);
|
|
75
110
|
this.buf.copy(newBuf, 0, 0, this.pos);
|
|
76
111
|
this.buf = newBuf;
|
|
77
112
|
}
|
|
78
113
|
|
|
114
|
+
mark() {
|
|
115
|
+
this.markPos = this.pos;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
isMarked() {
|
|
119
|
+
return this.markPos !== -1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
hasFlushed() {
|
|
123
|
+
return this.cmd.sequenceNo !== -1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
hasDataAfterMark() {
|
|
127
|
+
return this.bufContainDataAfterMark;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
bufIsAfterMaxPacketLength() {
|
|
131
|
+
return this.pos > this.maxPacketLength;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Reset mark flag and send bytes after mark flag.
|
|
136
|
+
*
|
|
137
|
+
* @return buffer after mark flag
|
|
138
|
+
*/
|
|
139
|
+
resetMark() {
|
|
140
|
+
this.pos = this.markPos;
|
|
141
|
+
this.markPos = -1;
|
|
142
|
+
if (this.bufContainDataAfterMark) {
|
|
143
|
+
const data = Buffer.allocUnsafe(this.pos - 4);
|
|
144
|
+
this.buf.copy(data, 0, 4, this.pos);
|
|
145
|
+
this.cmd.sequenceNo = -1;
|
|
146
|
+
this.cmd.compressSequenceNo = -1;
|
|
147
|
+
this.bufContainDataAfterMark = false;
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Send packet to socket.
|
|
155
|
+
*
|
|
156
|
+
* @throws IOException if socket error occur.
|
|
157
|
+
*/
|
|
158
|
+
flush() {
|
|
159
|
+
this.flushBuffer(true, 0);
|
|
160
|
+
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
|
|
161
|
+
this.cmd.sequenceNo = -1;
|
|
162
|
+
this.cmd.compressSequenceNo = -1;
|
|
163
|
+
this.cmdLength = 0;
|
|
164
|
+
this.markPos = -1;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
flushPacket() {
|
|
168
|
+
this.flushBuffer(false, 0);
|
|
169
|
+
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
|
|
170
|
+
this.cmdLength = 0;
|
|
171
|
+
this.markPos = -1;
|
|
172
|
+
}
|
|
173
|
+
|
|
79
174
|
startPacket(cmd) {
|
|
80
175
|
this.cmd = cmd;
|
|
81
176
|
this.pos = 4;
|
|
@@ -83,10 +178,10 @@ class PacketOutputStream {
|
|
|
83
178
|
|
|
84
179
|
writeInt8(value) {
|
|
85
180
|
if (this.pos + 1 >= this.buf.length) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
181
|
+
let b = Buffer.allocUnsafe(1);
|
|
182
|
+
b[0] = value;
|
|
183
|
+
this.writeBuffer(b, 0, 1);
|
|
184
|
+
return;
|
|
90
185
|
}
|
|
91
186
|
this.buf[this.pos++] = value;
|
|
92
187
|
}
|
|
@@ -94,7 +189,8 @@ class PacketOutputStream {
|
|
|
94
189
|
writeInt16(value) {
|
|
95
190
|
if (this.pos + 2 >= this.buf.length) {
|
|
96
191
|
let b = Buffer.allocUnsafe(2);
|
|
97
|
-
b
|
|
192
|
+
b[0] = value;
|
|
193
|
+
b[1] = value >>> 8;
|
|
98
194
|
this.writeBuffer(b, 0, 2);
|
|
99
195
|
return;
|
|
100
196
|
}
|
|
@@ -108,6 +204,23 @@ class PacketOutputStream {
|
|
|
108
204
|
this.buf[initPos + 1] = (this.pos - initPos - 2) >> 8;
|
|
109
205
|
}
|
|
110
206
|
|
|
207
|
+
writeInt24(value) {
|
|
208
|
+
if (this.pos + 3 >= this.buf.length) {
|
|
209
|
+
//not enough space remaining
|
|
210
|
+
let arr = Buffer.allocUnsafe(3);
|
|
211
|
+
arr[0] = value;
|
|
212
|
+
arr[1] = value >> 8;
|
|
213
|
+
arr[2] = value >> 16;
|
|
214
|
+
this.writeBuffer(arr, 0, 3);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this.buf[this.pos] = value;
|
|
219
|
+
this.buf[this.pos + 1] = value >> 8;
|
|
220
|
+
this.buf[this.pos + 2] = value >> 16;
|
|
221
|
+
this.pos += 3;
|
|
222
|
+
}
|
|
223
|
+
|
|
111
224
|
writeInt32(value) {
|
|
112
225
|
if (this.pos + 4 >= this.buf.length) {
|
|
113
226
|
//not enough space remaining
|
|
@@ -124,17 +237,47 @@ class PacketOutputStream {
|
|
|
124
237
|
this.pos += 4;
|
|
125
238
|
}
|
|
126
239
|
|
|
240
|
+
writeBigInt(value) {
|
|
241
|
+
if (this.pos + 8 >= this.buf.length) {
|
|
242
|
+
//not enough space remaining
|
|
243
|
+
let arr = Buffer.allocUnsafe(8);
|
|
244
|
+
arr.writeBigInt64LE(value, 0);
|
|
245
|
+
this.writeBuffer(arr, 0, 8);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this.buf.writeBigInt64LE(value, this.pos);
|
|
249
|
+
this.pos += 8;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
writeDouble(value) {
|
|
253
|
+
if (this.pos + 8 >= this.buf.length) {
|
|
254
|
+
//not enough space remaining
|
|
255
|
+
let arr = Buffer.allocUnsafe(8);
|
|
256
|
+
arr.writeDoubleLE(value, 0);
|
|
257
|
+
this.writeBuffer(arr, 0, 8);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
this.buf.writeDoubleLE(value, this.pos);
|
|
261
|
+
this.pos += 8;
|
|
262
|
+
}
|
|
263
|
+
|
|
127
264
|
writeLengthCoded(len) {
|
|
128
|
-
//length encoded can be null(0xfb) or bigger than 65k, but only if using binary protocol
|
|
129
|
-
//so not implemented for now
|
|
130
265
|
if (len < 0xfb) {
|
|
131
266
|
this.writeInt8(len);
|
|
132
267
|
return;
|
|
133
268
|
}
|
|
134
269
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
270
|
+
if (len < 65536) {
|
|
271
|
+
//max length is len < 0xffff
|
|
272
|
+
this.writeInt8(0xfc);
|
|
273
|
+
this.writeInt16(len);
|
|
274
|
+
} else if (len < 16777216) {
|
|
275
|
+
this.writeInt8(0xfd);
|
|
276
|
+
this.writeInt24(len);
|
|
277
|
+
} else {
|
|
278
|
+
this.writeInt8(0xfe);
|
|
279
|
+
this.writeBigInt(BigInt(len));
|
|
280
|
+
}
|
|
138
281
|
}
|
|
139
282
|
|
|
140
283
|
writeBuffer(arr, off, len) {
|
|
@@ -145,25 +288,43 @@ class PacketOutputStream {
|
|
|
145
288
|
|
|
146
289
|
//max buffer size
|
|
147
290
|
if (len > this.buf.length - this.pos) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
291
|
+
if (this.markPos !== -1) {
|
|
292
|
+
this.growBuffer(len);
|
|
293
|
+
if (this.markPos !== -1) {
|
|
294
|
+
this.flushBufferStopAtMark();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (len > this.buf.length - this.pos) {
|
|
299
|
+
//not enough space in buffer, will stream :
|
|
300
|
+
// fill buffer and flush until all data are snd
|
|
301
|
+
let remainingLen = len;
|
|
302
|
+
|
|
303
|
+
while (true) {
|
|
304
|
+
//filling buffer
|
|
305
|
+
let lenToFillBuffer = Math.min(MAX_BUFFER_SIZE - this.pos, remainingLen);
|
|
306
|
+
arr.copy(this.buf, this.pos, off, off + lenToFillBuffer);
|
|
307
|
+
remainingLen -= lenToFillBuffer;
|
|
308
|
+
off += lenToFillBuffer;
|
|
309
|
+
this.pos += lenToFillBuffer;
|
|
310
|
+
|
|
311
|
+
if (remainingLen === 0) return;
|
|
312
|
+
this.flushBuffer(false, remainingLen);
|
|
313
|
+
}
|
|
162
314
|
}
|
|
163
315
|
}
|
|
164
316
|
}
|
|
165
|
-
|
|
166
|
-
|
|
317
|
+
|
|
318
|
+
// node.js copy is fast only when copying big buffer.
|
|
319
|
+
// quick array copy is multiple time faster for small copy
|
|
320
|
+
if (len > 50) {
|
|
321
|
+
arr.copy(this.buf, this.pos, off, off + len);
|
|
322
|
+
this.pos += len;
|
|
323
|
+
} else {
|
|
324
|
+
for (let i = 0; i < len; ) {
|
|
325
|
+
this.buf[this.pos++] = arr[off + i++];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
167
328
|
}
|
|
168
329
|
|
|
169
330
|
/**
|
|
@@ -186,6 +347,12 @@ class PacketOutputStream {
|
|
|
186
347
|
}
|
|
187
348
|
}
|
|
188
349
|
|
|
350
|
+
writeLengthEncodedBuffer(buffer) {
|
|
351
|
+
const len = buffer.length;
|
|
352
|
+
this.writeLengthCoded(len);
|
|
353
|
+
this.writeBuffer(buffer, 0, len);
|
|
354
|
+
}
|
|
355
|
+
|
|
189
356
|
writeUtf8StringEscapeQuote(str) {
|
|
190
357
|
const charsLength = str.length;
|
|
191
358
|
|
|
@@ -208,17 +375,8 @@ class PacketOutputStream {
|
|
|
208
375
|
let currChar;
|
|
209
376
|
this.buf[this.pos++] = QUOTE;
|
|
210
377
|
//quick loop if only ASCII chars for faster escape
|
|
211
|
-
for (
|
|
212
|
-
|
|
213
|
-
charsOffset < charsLength && (currChar = str.charCodeAt(charsOffset)) < 0x80;
|
|
214
|
-
charsOffset++
|
|
215
|
-
) {
|
|
216
|
-
if (
|
|
217
|
-
currChar === SLASH ||
|
|
218
|
-
currChar === QUOTE ||
|
|
219
|
-
currChar === ZERO_BYTE ||
|
|
220
|
-
currChar === DBL_QUOTE
|
|
221
|
-
) {
|
|
378
|
+
for (; charsOffset < charsLength && (currChar = str.charCodeAt(charsOffset)) < 0x80; charsOffset++) {
|
|
379
|
+
if (currChar === SLASH || currChar === QUOTE || currChar === ZERO_BYTE || currChar === DBL_QUOTE) {
|
|
222
380
|
this.buf[this.pos++] = SLASH;
|
|
223
381
|
}
|
|
224
382
|
this.buf[this.pos++] = currChar;
|
|
@@ -228,12 +386,7 @@ class PacketOutputStream {
|
|
|
228
386
|
while (charsOffset < charsLength) {
|
|
229
387
|
currChar = str.charCodeAt(charsOffset++);
|
|
230
388
|
if (currChar < 0x80) {
|
|
231
|
-
if (
|
|
232
|
-
currChar === SLASH ||
|
|
233
|
-
currChar === QUOTE ||
|
|
234
|
-
currChar === ZERO_BYTE ||
|
|
235
|
-
currChar === DBL_QUOTE
|
|
236
|
-
) {
|
|
389
|
+
if (currChar === SLASH || currChar === QUOTE || currChar === ZERO_BYTE || currChar === DBL_QUOTE) {
|
|
237
390
|
this.buf[this.pos++] = SLASH;
|
|
238
391
|
}
|
|
239
392
|
this.buf[this.pos++] = currChar;
|
|
@@ -250,8 +403,7 @@ class PacketOutputStream {
|
|
|
250
403
|
const nextChar = str.charCodeAt(charsOffset);
|
|
251
404
|
if (nextChar >= 0xdc00 && nextChar < 0xe000) {
|
|
252
405
|
//is low surrogate
|
|
253
|
-
const surrogatePairs =
|
|
254
|
-
(currChar << 10) + nextChar + (0x010000 - (0xd800 << 10) - 0xdc00);
|
|
406
|
+
const surrogatePairs = (currChar << 10) + nextChar + (0x010000 - (0xd800 << 10) - 0xdc00);
|
|
255
407
|
this.buf[this.pos++] = 0xf0 | (surrogatePairs >> 18);
|
|
256
408
|
this.buf[this.pos++] = 0x80 | ((surrogatePairs >> 12) & 0x3f);
|
|
257
409
|
this.buf[this.pos++] = 0x80 | ((surrogatePairs >> 6) & 0x3f);
|
|
@@ -275,6 +427,14 @@ class PacketOutputStream {
|
|
|
275
427
|
this.buf[this.pos++] = QUOTE;
|
|
276
428
|
}
|
|
277
429
|
|
|
430
|
+
encodeIconvString(str) {
|
|
431
|
+
return Iconv.encode(str, this.encoding);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
encodeNodeString(str) {
|
|
435
|
+
return Buffer.from(str, this.encoding);
|
|
436
|
+
}
|
|
437
|
+
|
|
278
438
|
writeDefaultBufferString(str) {
|
|
279
439
|
//javascript use UCS-2 or UTF-16 string internal representation
|
|
280
440
|
//that means that string to byte will be a maximum of * 3
|
|
@@ -300,11 +460,39 @@ class PacketOutputStream {
|
|
|
300
460
|
this.pos += this.buf.write(str, this.pos, this.encoding);
|
|
301
461
|
}
|
|
302
462
|
|
|
463
|
+
writeDefaultBufferLengthEncodedString(str) {
|
|
464
|
+
//javascript use UCS-2 or UTF-16 string internal representation
|
|
465
|
+
//that means that string to byte will be a maximum of * 3
|
|
466
|
+
// (4 bytes utf-8 are represented on 2 UTF-16 characters)
|
|
467
|
+
//checking real length
|
|
468
|
+
let byteLength = Buffer.byteLength(str, this.encoding);
|
|
469
|
+
this.writeLengthCoded(byteLength);
|
|
470
|
+
|
|
471
|
+
if (byteLength > this.buf.length - this.pos) {
|
|
472
|
+
if (this.buf.length < MAX_BUFFER_SIZE) {
|
|
473
|
+
this.growBuffer(byteLength);
|
|
474
|
+
}
|
|
475
|
+
if (byteLength > this.buf.length - this.pos) {
|
|
476
|
+
//not enough space in buffer, will stream :
|
|
477
|
+
let strBuf = Buffer.from(str, this.encoding);
|
|
478
|
+
this.writeBuffer(strBuf, 0, strBuf.length);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
this.pos += this.buf.write(str, this.pos, this.encoding);
|
|
483
|
+
}
|
|
484
|
+
|
|
303
485
|
writeDefaultIconvString(str) {
|
|
304
486
|
let buf = Iconv.encode(str, this.encoding);
|
|
305
487
|
this.writeBuffer(buf, 0, buf.length);
|
|
306
488
|
}
|
|
307
489
|
|
|
490
|
+
writeDefaultIconvLengthEncodedString(str) {
|
|
491
|
+
let buf = Iconv.encode(str, this.encoding);
|
|
492
|
+
this.writeLengthCoded(buf.length);
|
|
493
|
+
this.writeBuffer(buf, 0, buf.length);
|
|
494
|
+
}
|
|
495
|
+
|
|
308
496
|
/**
|
|
309
497
|
* Parameters need to be properly escaped :
|
|
310
498
|
* following characters are to be escaped by "\" :
|
|
@@ -312,8 +500,9 @@ class PacketOutputStream {
|
|
|
312
500
|
* - \\
|
|
313
501
|
* - \'
|
|
314
502
|
* - \"
|
|
503
|
+
* - \032
|
|
315
504
|
* regex split part of string writing part, and escaping special char.
|
|
316
|
-
* Those chars are <= 7f meaning that this will work even with
|
|
505
|
+
* Those chars are <= 7f meaning that this will work even with multibyte encoding
|
|
317
506
|
*
|
|
318
507
|
* @param str string to escape.
|
|
319
508
|
*/
|
|
@@ -341,6 +530,59 @@ class PacketOutputStream {
|
|
|
341
530
|
this.writeInt8(QUOTE);
|
|
342
531
|
}
|
|
343
532
|
|
|
533
|
+
writeBinaryDate(date) {
|
|
534
|
+
const year = date.getFullYear();
|
|
535
|
+
const mon = date.getMonth() + 1;
|
|
536
|
+
const day = date.getDate();
|
|
537
|
+
const hour = date.getHours();
|
|
538
|
+
const min = date.getMinutes();
|
|
539
|
+
const sec = date.getSeconds();
|
|
540
|
+
const ms = date.getMilliseconds();
|
|
541
|
+
|
|
542
|
+
let len = ms === 0 ? 7 : 11;
|
|
543
|
+
//not enough space remaining
|
|
544
|
+
if (len + 1 > this.buf.length - this.pos) {
|
|
545
|
+
let tmpBuf = Buffer.allocUnsafe(len + 1);
|
|
546
|
+
|
|
547
|
+
tmpBuf[0] = len;
|
|
548
|
+
tmpBuf[1] = year;
|
|
549
|
+
tmpBuf[2] = year >>> 8;
|
|
550
|
+
tmpBuf[3] = mon;
|
|
551
|
+
tmpBuf[4] = day;
|
|
552
|
+
tmpBuf[5] = hour;
|
|
553
|
+
tmpBuf[6] = min;
|
|
554
|
+
tmpBuf[7] = sec;
|
|
555
|
+
if (ms !== 0) {
|
|
556
|
+
const micro = ms * 1000;
|
|
557
|
+
tmpBuf[8] = micro;
|
|
558
|
+
tmpBuf[9] = micro >>> 8;
|
|
559
|
+
tmpBuf[10] = micro >>> 16;
|
|
560
|
+
tmpBuf[11] = micro >>> 24;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
this.writeBuffer(tmpBuf, 0, len + 1);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
this.buf[this.pos] = len;
|
|
568
|
+
this.buf[this.pos + 1] = year;
|
|
569
|
+
this.buf[this.pos + 2] = year >>> 8;
|
|
570
|
+
this.buf[this.pos + 3] = mon;
|
|
571
|
+
this.buf[this.pos + 4] = day;
|
|
572
|
+
this.buf[this.pos + 5] = hour;
|
|
573
|
+
this.buf[this.pos + 6] = min;
|
|
574
|
+
this.buf[this.pos + 7] = sec;
|
|
575
|
+
|
|
576
|
+
if (ms !== 0) {
|
|
577
|
+
const micro = ms * 1000;
|
|
578
|
+
this.buf[this.pos + 8] = micro;
|
|
579
|
+
this.buf[this.pos + 9] = micro >>> 8;
|
|
580
|
+
this.buf[this.pos + 10] = micro >>> 16;
|
|
581
|
+
this.buf[this.pos + 11] = micro >>> 24;
|
|
582
|
+
}
|
|
583
|
+
this.pos += len + 1;
|
|
584
|
+
}
|
|
585
|
+
|
|
344
586
|
writeBufferEscape(val) {
|
|
345
587
|
let valLen = val.length;
|
|
346
588
|
if (valLen * 2 > this.buf.length - this.pos) {
|
|
@@ -380,6 +622,26 @@ class PacketOutputStream {
|
|
|
380
622
|
}
|
|
381
623
|
}
|
|
382
624
|
|
|
625
|
+
/**
|
|
626
|
+
* Count query size. If query size is greater than max_allowed_packet and nothing has been already
|
|
627
|
+
* send, throw an exception to avoid having the connection closed.
|
|
628
|
+
*
|
|
629
|
+
* @param length additional length to query size
|
|
630
|
+
* @param info current connection information
|
|
631
|
+
* @throws Error if query has not to be sent.
|
|
632
|
+
*/
|
|
633
|
+
checkMaxAllowedLength(length, info) {
|
|
634
|
+
if (this.opts.maxAllowedPacket && this.cmdLength + length >= this.maxAllowedPacket) {
|
|
635
|
+
// launch exception only if no packet has been sent.
|
|
636
|
+
return Errors.createError(
|
|
637
|
+
`query size (${this.cmdLength + length}) is >= to max_allowed_packet (${this.maxAllowedPacket})`,
|
|
638
|
+
Errors.ER_MAX_ALLOWED_PACKET,
|
|
639
|
+
info
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
644
|
+
|
|
383
645
|
/**
|
|
384
646
|
* Indicate if buffer contain any data.
|
|
385
647
|
* @returns {boolean}
|
|
@@ -392,111 +654,117 @@ class PacketOutputStream {
|
|
|
392
654
|
* Flush the internal buffer.
|
|
393
655
|
*/
|
|
394
656
|
flushBufferDebug(commandEnd, remainingLen) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
this.
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
this.cmd.constructor.name +
|
|
409
|
-
'(0,' +
|
|
410
|
-
this.pos +
|
|
411
|
-
')\n' +
|
|
412
|
-
packet
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (this.opts.debug) {
|
|
417
|
-
console.log(
|
|
418
|
-
'==> conn:%d %s\n%s',
|
|
419
|
-
this.info.threadId ? this.info.threadId : -1,
|
|
420
|
-
this.cmd.constructor.name + '(0,' + this.pos + ')',
|
|
421
|
-
Utils.log(this.opts, this.buf, 0, this.pos)
|
|
657
|
+
if (this.pos > 4) {
|
|
658
|
+
this.buf[0] = this.pos - 4;
|
|
659
|
+
this.buf[1] = (this.pos - 4) >>> 8;
|
|
660
|
+
this.buf[2] = (this.pos - 4) >>> 16;
|
|
661
|
+
this.buf[3] = ++this.cmd.sequenceNo;
|
|
662
|
+
this.stream.writeBuf(this.buf.subarray(0, this.pos), this.cmd);
|
|
663
|
+
this.stream.flush(true, this.cmd);
|
|
664
|
+
this.cmdLength += this.pos - 4;
|
|
665
|
+
|
|
666
|
+
this.opts.logger.network(
|
|
667
|
+
`==> conn:${this.info.threadId ? this.info.threadId : -1} ${
|
|
668
|
+
this.cmd.constructor.name + '(0,' + this.pos + ')'
|
|
669
|
+
}\n${Utils.log(this.opts, this.buf, 0, this.pos)}`
|
|
422
670
|
);
|
|
423
|
-
}
|
|
424
671
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (this.pos === MAX_BUFFER_SIZE) {
|
|
672
|
+
if (commandEnd && this.pos === MAX_BUFFER_SIZE) {
|
|
673
|
+
//if last packet fill the max size, must send an empty com to indicate that command end.
|
|
428
674
|
this.writeEmptyPacket();
|
|
429
|
-
} else {
|
|
430
|
-
this.stream.flush(true, this.cmd);
|
|
431
|
-
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
|
|
432
675
|
}
|
|
433
|
-
|
|
434
|
-
this.buf = allocateBuffer(remainingLen + 4);
|
|
676
|
+
this.buf = this.createBufferWithMinSize(remainingLen);
|
|
435
677
|
this.pos = 4;
|
|
436
678
|
}
|
|
437
679
|
}
|
|
438
680
|
|
|
681
|
+
/**
|
|
682
|
+
* Flush to last mark.
|
|
683
|
+
*/
|
|
684
|
+
flushBufferStopAtMark() {
|
|
685
|
+
const end = this.pos;
|
|
686
|
+
this.pos = this.markPos;
|
|
687
|
+
const tmpBuf = Buffer.allocUnsafe(Math.max(SMALL_BUFFER_SIZE, end + 4 - this.pos));
|
|
688
|
+
this.buf.copy(tmpBuf, 4, this.markPos, end);
|
|
689
|
+
this.flushBuffer(true, end - this.pos);
|
|
690
|
+
this.cmdLength = 0;
|
|
691
|
+
this.buf = tmpBuf;
|
|
692
|
+
this.pos = 4 + end - this.markPos;
|
|
693
|
+
this.markPos = -1;
|
|
694
|
+
this.bufContainDataAfterMark = true;
|
|
695
|
+
}
|
|
696
|
+
|
|
439
697
|
flushBufferBasic(commandEnd, remainingLen) {
|
|
440
698
|
this.buf[0] = this.pos - 4;
|
|
441
699
|
this.buf[1] = (this.pos - 4) >>> 8;
|
|
442
700
|
this.buf[2] = (this.pos - 4) >>> 16;
|
|
443
701
|
this.buf[3] = ++this.cmd.sequenceNo;
|
|
444
|
-
this.stream.writeBuf(this.buf.
|
|
445
|
-
|
|
702
|
+
this.stream.writeBuf(this.buf.subarray(0, this.pos), this.cmd);
|
|
703
|
+
this.stream.flush(true, this.cmd);
|
|
704
|
+
this.cmdLength += this.pos - 4;
|
|
705
|
+
if (commandEnd && this.pos === MAX_BUFFER_SIZE) {
|
|
446
706
|
//if last packet fill the max size, must send an empty com to indicate that command end.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
707
|
+
this.writeEmptyPacket();
|
|
708
|
+
}
|
|
709
|
+
this.buf = this.createBufferWithMinSize(remainingLen);
|
|
710
|
+
this.pos = 4;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
createBufferWithMinSize(remainingLen) {
|
|
714
|
+
let newCapacity;
|
|
715
|
+
if (remainingLen + 4 < SMALL_BUFFER_SIZE) {
|
|
716
|
+
newCapacity = SMALL_BUFFER_SIZE;
|
|
717
|
+
} else if (remainingLen + 4 < MEDIUM_BUFFER_SIZE) {
|
|
718
|
+
newCapacity = MEDIUM_BUFFER_SIZE;
|
|
719
|
+
} else if (remainingLen + 4 < LARGE_BUFFER_SIZE) {
|
|
720
|
+
newCapacity = LARGE_BUFFER_SIZE;
|
|
721
|
+
} else if (remainingLen + 4 < BIG_BUFFER_SIZE) {
|
|
722
|
+
newCapacity = BIG_BUFFER_SIZE;
|
|
453
723
|
} else {
|
|
454
|
-
|
|
455
|
-
this.pos = 4;
|
|
724
|
+
newCapacity = MAX_BUFFER_SIZE;
|
|
456
725
|
}
|
|
726
|
+
return Buffer.allocUnsafe(newCapacity);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
fastFlushDebug(cmd, packet) {
|
|
730
|
+
this.stream.writeBuf(packet, cmd);
|
|
731
|
+
this.stream.flush(true, cmd);
|
|
732
|
+
this.cmdLength += packet.length;
|
|
733
|
+
|
|
734
|
+
this.opts.logger.network(
|
|
735
|
+
`==> conn:${this.info.threadId ? this.info.threadId : -1} ${
|
|
736
|
+
cmd.constructor.name + '(0,' + packet.length + ')'
|
|
737
|
+
}\n${Utils.log(this.opts, packet, 0, packet.length)}`
|
|
738
|
+
);
|
|
739
|
+
this.cmdLength = 0;
|
|
740
|
+
this.markPos = -1;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
fastFlushBasic(cmd, packet) {
|
|
744
|
+
this.stream.writeBuf(packet, cmd);
|
|
745
|
+
this.stream.flush(true, cmd);
|
|
746
|
+
this.cmdLength = 0;
|
|
747
|
+
this.markPos = -1;
|
|
457
748
|
}
|
|
458
749
|
|
|
459
750
|
writeEmptyPacket() {
|
|
460
751
|
const emptyBuf = Buffer.from([0x00, 0x00, 0x00, ++this.cmd.sequenceNo]);
|
|
461
752
|
|
|
462
|
-
if (this.
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
packet
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
if (this.opts.debug) {
|
|
475
|
-
console.log(
|
|
476
|
-
'==> conn:%d %s\n%s',
|
|
477
|
-
this.info.threadId ? this.info.threadId : -1,
|
|
478
|
-
this.cmd.constructor.name + '(0,4)',
|
|
479
|
-
packet
|
|
480
|
-
);
|
|
481
|
-
}
|
|
753
|
+
if (this.debug) {
|
|
754
|
+
this.opts.logger.network(
|
|
755
|
+
`==> conn:${this.info.threadId ? this.info.threadId : -1} ${this.cmd.constructor.name}(0,4)\n${Utils.log(
|
|
756
|
+
this.opts,
|
|
757
|
+
emptyBuf,
|
|
758
|
+
0,
|
|
759
|
+
4
|
|
760
|
+
)}`
|
|
761
|
+
);
|
|
482
762
|
}
|
|
483
763
|
|
|
484
764
|
this.stream.writeBuf(emptyBuf, this.cmd);
|
|
485
765
|
this.stream.flush(true, this.cmd);
|
|
766
|
+
this.cmdLength = 0;
|
|
486
767
|
}
|
|
487
768
|
}
|
|
488
769
|
|
|
489
|
-
function allocateBuffer(len) {
|
|
490
|
-
if (len < SMALL_BUFFER_SIZE) {
|
|
491
|
-
return Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
|
|
492
|
-
} else if (len < MEDIUM_BUFFER_SIZE) {
|
|
493
|
-
return Buffer.allocUnsafe(MEDIUM_BUFFER_SIZE);
|
|
494
|
-
} else if (len < LARGE_BUFFER_SIZE) {
|
|
495
|
-
return Buffer.allocUnsafe(LARGE_BUFFER_SIZE);
|
|
496
|
-
} else if (len < BIG_BUFFER_SIZE) {
|
|
497
|
-
return Buffer.allocUnsafe(BIG_BUFFER_SIZE);
|
|
498
|
-
}
|
|
499
|
-
return Buffer.allocUnsafe(MAX_BUFFER_SIZE);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
770
|
module.exports = PacketOutputStream;
|