@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.
Files changed (105) hide show
  1. package/README.md +34 -34
  2. package/README.zh-CN.md +34 -34
  3. package/client.d.ts +1 -1
  4. package/client.js +1 -1
  5. package/dist/externalVersion.js +5 -5
  6. package/dist/locale/en-US.json +48 -48
  7. package/dist/locale/es-ES.json +9 -9
  8. package/dist/locale/ko_KR.json +11 -11
  9. package/dist/locale/pt-BR.json +9 -9
  10. package/dist/locale/zh-CN.json +58 -58
  11. package/dist/node_modules/mariadb/callback.js +43 -8
  12. package/dist/node_modules/mariadb/check-node.js +30 -0
  13. package/dist/node_modules/mariadb/lib/cluster-callback.js +84 -0
  14. package/dist/node_modules/mariadb/lib/cluster.js +446 -0
  15. package/dist/node_modules/mariadb/lib/cmd/batch-bulk.js +576 -177
  16. package/dist/node_modules/mariadb/lib/cmd/change-user.js +54 -44
  17. package/dist/node_modules/mariadb/lib/cmd/class/ok-packet.js +3 -2
  18. package/dist/node_modules/mariadb/lib/cmd/class/prepare-cache-wrapper.js +46 -0
  19. package/dist/node_modules/mariadb/lib/cmd/class/prepare-result-packet.js +141 -0
  20. package/dist/node_modules/mariadb/lib/cmd/class/prepare-wrapper.js +70 -0
  21. package/dist/node_modules/mariadb/lib/cmd/close-prepare.js +38 -0
  22. package/dist/node_modules/mariadb/lib/cmd/column-definition.js +145 -47
  23. package/dist/node_modules/mariadb/lib/cmd/command.js +41 -75
  24. package/dist/node_modules/mariadb/lib/cmd/decoder/binary-decoder.js +282 -0
  25. package/dist/node_modules/mariadb/lib/cmd/decoder/text-decoder.js +210 -0
  26. package/dist/node_modules/mariadb/lib/cmd/{common-binary-cmd.js → encoder/binary-encoder.js} +34 -77
  27. package/dist/node_modules/mariadb/lib/cmd/encoder/text-encoder.js +311 -0
  28. package/dist/node_modules/mariadb/lib/cmd/execute-stream.js +61 -0
  29. package/dist/node_modules/mariadb/lib/cmd/execute.js +338 -0
  30. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/caching-sha2-password-auth.js +25 -62
  31. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/clear-password-auth.js +39 -6
  32. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/ed25519-password-auth.js +48 -16
  33. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/handshake.js +198 -0
  34. package/dist/node_modules/mariadb/lib/cmd/handshake/{initial-handshake.js → auth/initial-handshake.js} +10 -8
  35. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/native-password-auth.js +22 -9
  36. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/pam-password-auth.js +9 -4
  37. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/parsec-auth.js +115 -0
  38. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/plugin-auth.js +12 -5
  39. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/sha256-password-auth.js +44 -33
  40. package/dist/node_modules/mariadb/lib/cmd/handshake/authentication.js +335 -0
  41. package/dist/node_modules/mariadb/lib/cmd/handshake/client-capabilities.js +20 -19
  42. package/dist/node_modules/mariadb/lib/cmd/handshake/ssl-request.js +6 -3
  43. package/dist/node_modules/mariadb/lib/cmd/parser.js +861 -0
  44. package/dist/node_modules/mariadb/lib/cmd/ping.js +17 -18
  45. package/dist/node_modules/mariadb/lib/cmd/prepare.js +170 -0
  46. package/dist/node_modules/mariadb/lib/cmd/query.js +281 -144
  47. package/dist/node_modules/mariadb/lib/cmd/quit.js +9 -6
  48. package/dist/node_modules/mariadb/lib/cmd/reset.js +15 -19
  49. package/dist/node_modules/mariadb/lib/cmd/stream.js +21 -6
  50. package/dist/node_modules/mariadb/lib/config/cluster-options.js +23 -0
  51. package/dist/node_modules/mariadb/lib/config/connection-options.js +196 -132
  52. package/dist/node_modules/mariadb/lib/config/pool-options.js +27 -19
  53. package/dist/node_modules/mariadb/lib/connection-callback.js +492 -120
  54. package/dist/node_modules/mariadb/lib/connection-promise.js +372 -0
  55. package/dist/node_modules/mariadb/lib/connection.js +1739 -1016
  56. package/dist/node_modules/mariadb/lib/const/capabilities.js +36 -30
  57. package/dist/node_modules/mariadb/lib/const/collations.js +972 -36
  58. package/dist/node_modules/mariadb/lib/const/connection_status.js +3 -0
  59. package/dist/node_modules/mariadb/lib/const/error-code.js +35 -11
  60. package/dist/node_modules/mariadb/lib/const/field-detail.js +3 -0
  61. package/dist/node_modules/mariadb/lib/const/field-type.js +7 -4
  62. package/dist/node_modules/mariadb/lib/const/server-status.js +4 -1
  63. package/dist/node_modules/mariadb/lib/const/state-change.js +3 -0
  64. package/dist/node_modules/mariadb/lib/filtered-cluster-callback.js +136 -0
  65. package/dist/node_modules/mariadb/lib/filtered-cluster.js +118 -0
  66. package/dist/node_modules/mariadb/lib/io/compression-input-stream.js +14 -13
  67. package/dist/node_modules/mariadb/lib/io/compression-output-stream.js +21 -18
  68. package/dist/node_modules/mariadb/lib/io/packet-input-stream.js +75 -64
  69. package/dist/node_modules/mariadb/lib/io/packet-node-encoded.js +13 -9
  70. package/dist/node_modules/mariadb/lib/io/packet-node-iconv.js +12 -10
  71. package/dist/node_modules/mariadb/lib/io/packet-output-stream.js +402 -134
  72. package/dist/node_modules/mariadb/lib/io/packet.js +287 -202
  73. package/dist/node_modules/mariadb/lib/lru-prepare-cache.js +84 -0
  74. package/dist/node_modules/mariadb/lib/misc/connection-information.js +15 -32
  75. package/dist/node_modules/mariadb/lib/misc/errors.js +68 -25
  76. package/dist/node_modules/mariadb/lib/misc/parse.js +207 -711
  77. package/dist/node_modules/mariadb/lib/misc/utils.js +34 -62
  78. package/dist/node_modules/mariadb/lib/pool-callback.js +213 -174
  79. package/dist/node_modules/mariadb/lib/pool-promise.js +228 -94
  80. package/dist/node_modules/mariadb/lib/pool.js +951 -0
  81. package/dist/node_modules/mariadb/package.json +1 -1
  82. package/dist/node_modules/mariadb/promise.js +1 -34
  83. package/dist/node_modules/mariadb/types/callback.d.ts +207 -0
  84. package/dist/node_modules/mariadb/types/index.d.ts +94 -674
  85. package/dist/node_modules/mariadb/types/share.d.ts +804 -0
  86. package/dist/node_modules/qs/package.json +1 -1
  87. package/dist/server/actions/apps.js +2 -2
  88. package/dist/server/app-lifecycle.d.ts +1 -1
  89. package/dist/server/app-lifecycle.js +4 -4
  90. package/dist/server/models/application.d.ts +1 -1
  91. package/package.json +7 -7
  92. package/server.d.ts +2 -2
  93. package/server.js +1 -1
  94. package/dist/node_modules/mariadb/lib/cmd/batch-rewrite.js +0 -372
  95. package/dist/node_modules/mariadb/lib/cmd/common-text-cmd.js +0 -427
  96. package/dist/node_modules/mariadb/lib/cmd/handshake/client-handshake-response.js +0 -126
  97. package/dist/node_modules/mariadb/lib/cmd/handshake/handshake.js +0 -292
  98. package/dist/node_modules/mariadb/lib/cmd/resultset.js +0 -607
  99. package/dist/node_modules/mariadb/lib/config/pool-cluster-options.js +0 -19
  100. package/dist/node_modules/mariadb/lib/filtered-pool-cluster.js +0 -81
  101. package/dist/node_modules/mariadb/lib/io/bulk-packet.js +0 -590
  102. package/dist/node_modules/mariadb/lib/io/rewrite-packet.js +0 -481
  103. package/dist/node_modules/mariadb/lib/pool-base.js +0 -611
  104. package/dist/node_modules/mariadb/lib/pool-cluster-callback.js +0 -66
  105. 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 = 1024;
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 = /[\0\"\'\\\b\n\r\t\u001A]/g; // eslint-disable-line no-control-regex
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.changeEncoding(this.opts.collation);
33
- this.changeDebug(this.opts.logPackets, this.opts.debug);
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(logPackets, debug) {
54
- this.logPackets = logPackets;
70
+ changeDebug(debug) {
55
71
  this.debug = debug;
56
- this.flushBuffer =
57
- this.logPackets || this.debug ? this.flushBufferDebug : this.flushBufferBasic;
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 newCapacity = MAX_BUFFER_SIZE;
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
- if (this.pos >= MAX_BUFFER_SIZE) {
87
- //buffer is more than a Packet, must flushBuffer()
88
- this.flushBuffer(false, 1);
89
- } else this.growBuffer(1);
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.writeUInt16LE(value, 0);
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
- //max length is len < 0xffff
136
- this.writeInt8(0xfc);
137
- this.writeInt16(len);
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
- //not enough space in buffer, will stream :
149
- // fill buffer and flush until all data are snd
150
- let remainingLen = len;
151
-
152
- while (true) {
153
- //filling buffer
154
- let lenToFillBuffer = Math.min(MAX_BUFFER_SIZE - this.pos, remainingLen);
155
- arr.copy(this.buf, this.pos, off, off + lenToFillBuffer);
156
- remainingLen -= lenToFillBuffer;
157
- off += lenToFillBuffer;
158
- this.pos += lenToFillBuffer;
159
-
160
- if (remainingLen === 0) return;
161
- this.flushBuffer(false, remainingLen);
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
- arr.copy(this.buf, this.pos, off, off + len);
166
- this.pos += len;
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 multi-byte encoding
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
- this.buf[0] = this.pos - 4;
396
- this.buf[1] = (this.pos - 4) >>> 8;
397
- this.buf[2] = (this.pos - 4) >>> 16;
398
- this.buf[3] = ++this.cmd.sequenceNo;
399
-
400
- this.stream.writeBuf(this.buf.slice(0, this.pos), this.cmd);
401
-
402
- const packet = Utils.log(this.opts, this.buf, 0, this.pos);
403
- if (this.opts.logPackets) {
404
- this.info.addPacket(
405
- '==> conn:' +
406
- (this.info.threadId ? this.info.threadId : -1) +
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
- if (commandEnd) {
426
- //if last packet fill the max size, must send an empty com to indicate that command end.
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
- } else {
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.slice(0, this.pos), this.cmd);
445
- if (commandEnd) {
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
- if (this.pos === MAX_BUFFER_SIZE) {
448
- this.writeEmptyPacket();
449
- } else {
450
- this.stream.flush(true, this.cmd);
451
- this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
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
- this.buf = allocateBuffer(remainingLen + 4);
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.opts.logPackets || this.opts.debug) {
463
- const packet = Utils.log(this.opts, emptyBuf, 0, 4);
464
- if (this.opts.logPackets) {
465
- this.info.addPacket(
466
- '==> conn:' +
467
- (this.info.threadId ? this.info.threadId : -1) +
468
- ' ' +
469
- this.cmd.constructor.name +
470
- '(0,4)\n' +
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;