@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,17 +1,23 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2024 MariaDB Corporation Ab
3
+
1
4
  'use strict';
2
5
 
3
- const CommonText = require('./common-text-cmd');
6
+ const Parser = require('./parser');
4
7
  const Errors = require('../misc/errors');
5
8
  const Parse = require('../misc/parse');
9
+ const TextEncoder = require('./encoder/text-encoder');
10
+ const { Readable } = require('stream');
6
11
  const QUOTE = 0x27;
7
12
 
8
13
  /**
9
14
  * Protocol COM_QUERY
10
15
  * see : https://mariadb.com/kb/en/library/com_query/
11
16
  */
12
- class Query extends CommonText {
13
- constructor(resolve, reject, options, connOpts, sql, values) {
14
- super(resolve, reject, options, connOpts, sql, values);
17
+ class Query extends Parser {
18
+ constructor(resolve, reject, connOpts, cmdParam) {
19
+ super(resolve, reject, connOpts, cmdParam);
20
+ this.binary = false;
15
21
  }
16
22
 
17
23
  /**
@@ -22,33 +28,37 @@ class Query extends CommonText {
22
28
  * @param info connection information
23
29
  */
24
30
  start(out, opts, info) {
31
+ if (opts.logger.query) opts.logger.query(`QUERY: ${opts.logParam ? this.displaySql() : this.sql}`);
32
+ this.onPacketReceive = this.readResponsePacket;
25
33
  if (this.initialValues === undefined) {
26
34
  //shortcut if no parameters
27
35
  out.startPacket(this);
28
36
  out.writeInt8(0x03);
29
37
  if (!this.handleTimeout(out, info)) return;
30
38
  out.writeString(this.sql);
31
- out.flushBuffer(true);
39
+ out.flush();
32
40
  this.emit('send_end');
33
- return (this.onPacketReceive = this.readResponsePacket);
41
+ return;
34
42
  }
35
43
 
44
+ this.encodedSql = out.encodeString(this.sql);
45
+
36
46
  if (this.opts.namedPlaceholders) {
37
47
  try {
38
48
  const parsed = Parse.splitQueryPlaceholder(
39
- this.sql,
49
+ this.encodedSql,
40
50
  info,
41
51
  this.initialValues,
42
- this.displaySql.bind(this)
52
+ this.opts.logParam ? this.displaySql.bind(this) : () => this.sql
43
53
  );
44
- this.queryParts = parsed.parts;
54
+ this.paramPositions = parsed.paramPositions;
45
55
  this.values = parsed.values;
46
56
  } catch (err) {
47
57
  this.emit('send_end');
48
58
  return this.throwError(err, info);
49
59
  }
50
60
  } else {
51
- this.queryParts = Parse.splitQuery(this.sql);
61
+ this.paramPositions = Parse.splitQuery(this.encodedSql);
52
62
  this.values = Array.isArray(this.initialValues) ? this.initialValues : [this.initialValues];
53
63
  if (!this.validateParameters(info)) return;
54
64
  }
@@ -56,54 +66,185 @@ class Query extends CommonText {
56
66
  out.startPacket(this);
57
67
  out.writeInt8(0x03);
58
68
  if (!this.handleTimeout(out, info)) return;
59
- out.writeString(this.queryParts[0]);
60
- this.onPacketReceive = this.readResponsePacket;
69
+
70
+ this.paramPos = 0;
71
+ this.sqlPos = 0;
61
72
 
62
73
  //********************************************
63
74
  // send params
64
75
  //********************************************
65
- const len = this.queryParts.length;
66
- for (let i = 1; i < len; i++) {
67
- const value = this.values[i - 1];
68
-
69
- if (
70
- value !== null &&
71
- typeof value === 'object' &&
72
- typeof value.pipe === 'function' &&
73
- typeof value.read === 'function'
74
- ) {
75
- this.sending = true;
76
- //********************************************
77
- // param is stream,
78
- // now all params will be written by event
79
- //********************************************
80
- this.registerStreamSendEvent(out, info);
81
- this.currentParam = i;
82
- out.writeInt8(QUOTE); //'
83
-
84
- value.on('data', function (chunk) {
85
- out.writeBufferEscape(chunk);
86
- });
76
+ const len = this.paramPositions.length / 2;
77
+ for (this.valueIdx = 0; this.valueIdx < len; ) {
78
+ out.writeBuffer(this.encodedSql, this.sqlPos, this.paramPositions[this.paramPos++] - this.sqlPos);
79
+ this.sqlPos = this.paramPositions[this.paramPos++];
87
80
 
88
- value.on(
89
- 'end',
90
- function () {
81
+ const value = this.values[this.valueIdx++];
82
+ if (value == null) {
83
+ out.writeStringAscii('NULL');
84
+ continue;
85
+ }
86
+ switch (typeof value) {
87
+ case 'boolean':
88
+ out.writeStringAscii(value ? 'true' : 'false');
89
+ break;
90
+ case 'bigint':
91
+ case 'number':
92
+ out.writeStringAscii(`${value}`);
93
+ break;
94
+ case 'string':
95
+ out.writeStringEscapeQuote(value);
96
+ break;
97
+ case 'object':
98
+ if (typeof value.pipe === 'function' && typeof value.read === 'function') {
99
+ this.sending = true;
100
+ //********************************************
101
+ // param is stream,
102
+ // now all params will be written by event
103
+ //********************************************
104
+ this.paramWritten = this._paramWritten.bind(this, out, info);
91
105
  out.writeInt8(QUOTE); //'
92
- out.writeString(this.queryParts[this.currentParam++]);
93
- this.paramWritten();
94
- }.bind(this)
95
- );
106
+ value.on('data', out.writeBufferEscape.bind(out));
96
107
 
97
- return;
98
- } else {
99
- //********************************************
100
- // param isn't stream. directly write in buffer
101
- //********************************************
102
- this.writeParam(out, value, this.opts, info);
103
- out.writeString(this.queryParts[i]);
108
+ value.on(
109
+ 'end',
110
+ function () {
111
+ out.writeInt8(QUOTE); //'
112
+ this.paramWritten();
113
+ }.bind(this)
114
+ );
115
+ return;
116
+ }
117
+
118
+ if (Object.prototype.toString.call(value) === '[object Date]') {
119
+ out.writeStringAscii(TextEncoder.getLocalDate(value));
120
+ } else if (Buffer.isBuffer(value)) {
121
+ out.writeStringAscii("_BINARY '");
122
+ out.writeBufferEscape(value);
123
+ out.writeInt8(QUOTE);
124
+ } else if (typeof value.toSqlString === 'function') {
125
+ out.writeStringEscapeQuote(String(value.toSqlString()));
126
+ } else if (Array.isArray(value)) {
127
+ if (opts.arrayParenthesis) {
128
+ out.writeStringAscii('(');
129
+ }
130
+ for (let i = 0; i < value.length; i++) {
131
+ if (i !== 0) out.writeStringAscii(',');
132
+ if (value[i] == null) {
133
+ out.writeStringAscii('NULL');
134
+ } else TextEncoder.writeParam(out, value[i], opts, info);
135
+ }
136
+ if (opts.arrayParenthesis) {
137
+ out.writeStringAscii(')');
138
+ }
139
+ } else {
140
+ if (
141
+ value.type != null &&
142
+ [
143
+ 'Point',
144
+ 'LineString',
145
+ 'Polygon',
146
+ 'MultiPoint',
147
+ 'MultiLineString',
148
+ 'MultiPolygon',
149
+ 'GeometryCollection'
150
+ ].includes(value.type)
151
+ ) {
152
+ //GeoJSON format.
153
+ let prefix =
154
+ (info.isMariaDB() && info.hasMinVersion(10, 1, 4)) || (!info.isMariaDB() && info.hasMinVersion(5, 7, 6))
155
+ ? 'ST_'
156
+ : '';
157
+ switch (value.type) {
158
+ case 'Point':
159
+ out.writeStringAscii(
160
+ prefix + "PointFromText('POINT(" + TextEncoder.geoPointToString(value.coordinates) + ")')"
161
+ );
162
+ break;
163
+
164
+ case 'LineString':
165
+ out.writeStringAscii(
166
+ prefix + "LineFromText('LINESTRING(" + TextEncoder.geoArrayPointToString(value.coordinates) + ")')"
167
+ );
168
+ break;
169
+
170
+ case 'Polygon':
171
+ out.writeStringAscii(
172
+ prefix +
173
+ "PolygonFromText('POLYGON(" +
174
+ TextEncoder.geoMultiArrayPointToString(value.coordinates) +
175
+ ")')"
176
+ );
177
+ break;
178
+
179
+ case 'MultiPoint':
180
+ out.writeStringAscii(
181
+ prefix +
182
+ "MULTIPOINTFROMTEXT('MULTIPOINT(" +
183
+ TextEncoder.geoArrayPointToString(value.coordinates) +
184
+ ")')"
185
+ );
186
+ break;
187
+
188
+ case 'MultiLineString':
189
+ out.writeStringAscii(
190
+ prefix +
191
+ "MLineFromText('MULTILINESTRING(" +
192
+ TextEncoder.geoMultiArrayPointToString(value.coordinates) +
193
+ ")')"
194
+ );
195
+ break;
196
+
197
+ case 'MultiPolygon':
198
+ out.writeStringAscii(
199
+ prefix +
200
+ "MPolyFromText('MULTIPOLYGON(" +
201
+ TextEncoder.geoMultiPolygonToString(value.coordinates) +
202
+ ")')"
203
+ );
204
+ break;
205
+
206
+ case 'GeometryCollection':
207
+ out.writeStringAscii(
208
+ prefix +
209
+ "GeomCollFromText('GEOMETRYCOLLECTION(" +
210
+ TextEncoder.geometricCollectionToString(value.geometries) +
211
+ ")')"
212
+ );
213
+ break;
214
+ }
215
+ } else if (String === value.constructor) {
216
+ out.writeStringEscapeQuote(value);
217
+ break;
218
+ } else {
219
+ if (opts.permitSetMultiParamEntries) {
220
+ let first = true;
221
+ for (let key in value) {
222
+ const val = value[key];
223
+ if (typeof val === 'function') continue;
224
+ if (first) {
225
+ first = false;
226
+ } else {
227
+ out.writeStringAscii(',');
228
+ }
229
+ out.writeString('`' + key + '`');
230
+ if (val == null) {
231
+ out.writeStringAscii('=NULL');
232
+ } else {
233
+ out.writeStringAscii('=');
234
+ TextEncoder.writeParam(out, val, opts, info);
235
+ }
236
+ }
237
+ if (first) out.writeStringEscapeQuote(JSON.stringify(value));
238
+ } else {
239
+ out.writeStringEscapeQuote(JSON.stringify(value));
240
+ }
241
+ }
242
+ }
243
+ break;
104
244
  }
105
245
  }
106
- out.flushBuffer(true);
246
+ out.writeBuffer(this.encodedSql, this.sqlPos, this.encodedSql.length - this.sqlPos);
247
+ out.flush();
107
248
  this.emit('send_end');
108
249
  }
109
250
 
@@ -117,35 +258,24 @@ class Query extends CommonText {
117
258
  if (this.opts.timeout) {
118
259
  if (info.isMariaDB()) {
119
260
  if (info.hasMinVersion(10, 1, 2)) {
120
- out.writeString('SET STATEMENT max_statement_time=' + this.opts.timeout / 1000 + ' FOR ');
261
+ out.writeString(`SET STATEMENT max_statement_time=${this.opts.timeout / 1000} FOR `);
121
262
  return true;
122
263
  } else {
123
- const err = Errors.createError(
124
- 'Cannot use timeout for MariaDB server before 10.1.2. timeout value: ' +
125
- this.opts.timeout,
126
- this.sql,
127
- false,
128
- info,
129
- 'HY000',
130
- Errors.ER_TIMEOUT_NOT_SUPPORTED
264
+ this.sendCancelled(
265
+ `Cannot use timeout for xpand/MariaDB server before 10.1.2. timeout value: ${this.opts.timeout}`,
266
+ Errors.ER_TIMEOUT_NOT_SUPPORTED,
267
+ info
131
268
  );
132
- this.emit('send_end');
133
- this.throwError(err, info);
134
269
  return false;
135
270
  }
136
271
  } else {
137
272
  //not available for MySQL
138
273
  // max_execution time exist, but only for select, and as hint
139
- const err = Errors.createError(
140
- 'Cannot use timeout for MySQL server. timeout value: ' + this.opts.timeout,
141
- this.sql,
142
- false,
143
- info,
144
- 'HY000',
145
- Errors.ER_TIMEOUT_NOT_SUPPORTED
274
+ this.sendCancelled(
275
+ `Cannot use timeout for MySQL server. timeout value: ${this.opts.timeout}`,
276
+ Errors.ER_TIMEOUT_NOT_SUPPORTED,
277
+ info
146
278
  );
147
- this.emit('send_end');
148
- this.throwError(err, info);
149
279
  return false;
150
280
  }
151
281
  }
@@ -160,95 +290,102 @@ class Query extends CommonText {
160
290
  */
161
291
  validateParameters(info) {
162
292
  //validate parameter size.
163
- if (this.queryParts.length - 1 > this.values.length) {
164
- this.emit('send_end');
165
- this.throwNewError(
166
- 'Parameter at position ' + (this.values.length + 1) + ' is not set',
167
- false,
168
- info,
169
- 'HY000',
170
- Errors.ER_MISSING_PARAMETER
293
+ if (this.paramPositions.length / 2 > this.values.length) {
294
+ this.sendCancelled(
295
+ `Parameter at position ${this.values.length + 1} is not set`,
296
+ Errors.ER_MISSING_PARAMETER,
297
+ info
171
298
  );
172
299
  return false;
173
300
  }
301
+ return true;
302
+ }
174
303
 
175
- //validate parameter is defined.
176
- for (let i = 0; i < this.queryParts.length - 1; i++) {
177
- if (this.values[i] === undefined) {
304
+ _paramWritten(out, info) {
305
+ while (true) {
306
+ if (this.valueIdx === this.paramPositions.length / 2) {
307
+ //********************************************
308
+ // all parameters are written.
309
+ // flush packet
310
+ //********************************************
311
+ out.writeBuffer(this.encodedSql, this.sqlPos, this.encodedSql.length - this.sqlPos);
312
+ out.flush();
313
+ this.sending = false;
178
314
  this.emit('send_end');
179
- this.throwNewError(
180
- 'Parameter at position ' + (i + 1) + ' is undefined\n' + this.displaySql(),
181
- false,
182
- info,
183
- 'HY000',
184
- Errors.ER_PARAMETER_UNDEFINED
185
- );
186
- return false;
187
- }
188
- }
315
+ return;
316
+ } else {
317
+ const value = this.values[this.valueIdx++];
318
+ out.writeBuffer(this.encodedSql, this.sqlPos, this.paramPositions[this.paramPos++] - this.sqlPos);
319
+ this.sqlPos = this.paramPositions[this.paramPos++];
189
320
 
190
- return true;
191
- }
321
+ if (value == null) {
322
+ out.writeStringAscii('NULL');
323
+ continue;
324
+ }
192
325
 
193
- /**
194
- * Define params events.
195
- * Each parameter indicate that he is written to socket,
196
- * emitting event so next stream parameter can be written.
197
- */
198
- registerStreamSendEvent(out, info) {
199
- // note : Implementation use recursive calls, but stack won't never get near v8 max call stack size
200
- //since event launched for stream parameter only
201
- this.paramWritten = function () {
202
- while (true) {
203
- if (this.currentParam === this.queryParts.length) {
326
+ if (typeof value === 'object' && typeof value.pipe === 'function' && typeof value.read === 'function') {
204
327
  //********************************************
205
- // all parameters are written.
206
- // flush packet
328
+ // param is stream,
207
329
  //********************************************
208
- out.flushBuffer(true);
209
- this.sending = false;
210
- this.emit('send_end');
330
+ out.writeInt8(QUOTE);
331
+ value.once(
332
+ 'end',
333
+ function () {
334
+ out.writeInt8(QUOTE);
335
+ this._paramWritten(out, info);
336
+ }.bind(this)
337
+ );
338
+ value.on('data', out.writeBufferEscape.bind(out));
211
339
  return;
212
- } else {
213
- const value = this.values[this.currentParam - 1];
340
+ }
214
341
 
215
- if (value === null) {
216
- out.writeStringAscii('NULL');
217
- out.writeString(this.queryParts[this.currentParam++]);
218
- continue;
219
- }
342
+ //********************************************
343
+ // param isn't stream. directly write in buffer
344
+ //********************************************
345
+ TextEncoder.writeParam(out, value, this.opts, info);
346
+ }
347
+ }
348
+ }
220
349
 
221
- if (
222
- typeof value === 'object' &&
223
- typeof value.pipe === 'function' &&
224
- typeof value.read === 'function'
225
- ) {
226
- //********************************************
227
- // param is stream,
228
- //********************************************
229
- out.writeInt8(QUOTE);
230
- value.once(
231
- 'end',
232
- function () {
233
- out.writeInt8(QUOTE);
234
- out.writeString(this.queryParts[this.currentParam++]);
235
- this.paramWritten();
236
- }.bind(this)
237
- );
238
- value.on('data', function (chunk) {
239
- out.writeBufferEscape(chunk);
240
- });
241
- return;
242
- }
350
+ _stream(socket, options) {
351
+ this.socket = socket;
352
+ options = options || {};
353
+ options.objectMode = true;
354
+ options.read = () => {
355
+ this.socket.resume();
356
+ };
357
+ this.inStream = new Readable(options);
243
358
 
244
- //********************************************
245
- // param isn't stream. directly write in buffer
246
- //********************************************
247
- this.writeParam(out, value, this.opts, info);
248
- out.writeString(this.queryParts[this.currentParam++]);
249
- }
250
- }
359
+ this.on('fields', function (meta) {
360
+ this.inStream.emit('fields', meta);
361
+ });
362
+
363
+ this.on('error', function (err) {
364
+ this.inStream.emit('error', err);
365
+ });
366
+
367
+ this.on('close', function (err) {
368
+ this.inStream.emit('error', err);
369
+ });
370
+
371
+ this.on('end', function (err) {
372
+ if (err) this.inStream.emit('error', err);
373
+ this.socket.resume();
374
+ this.inStream.push(null);
375
+ });
376
+
377
+ this.inStream.close = function () {
378
+ this.handleNewRows = () => {};
379
+ this.socket.resume();
251
380
  }.bind(this);
381
+
382
+ this.handleNewRows = function (row) {
383
+ if (!this.inStream.push(row)) {
384
+ this.socket.pause();
385
+ }
386
+ };
387
+
388
+ return this.inStream;
252
389
  }
253
390
  }
254
391
 
@@ -1,23 +1,26 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2024 MariaDB Corporation Ab
3
+
1
4
  'use strict';
2
5
 
3
6
  const Command = require('./command');
7
+ const QUIT_COMMAND = new Uint8Array([1, 0, 0, 0, 0x01]);
4
8
 
5
9
  /**
6
10
  * Quit (close connection)
7
11
  * see https://mariadb.com/kb/en/library/com_quit/
8
12
  */
9
13
  class Quit extends Command {
10
- constructor(resolve, reject) {
11
- super(resolve, reject);
14
+ constructor(cmdParam, resolve, reject) {
15
+ super(cmdParam, resolve, reject);
12
16
  }
13
17
 
14
18
  start(out, opts, info) {
15
- out.startPacket(this);
16
- out.writeInt8(0x01);
17
- out.flushBuffer(true);
19
+ if (opts.logger.query) opts.logger.query('QUIT');
20
+ this.onPacketReceive = this.skipResults;
21
+ out.fastFlush(this, QUIT_COMMAND);
18
22
  this.emit('send_end');
19
23
  this.successEnd();
20
- this.onPacketReceive = this.skipResults;
21
24
  }
22
25
 
23
26
  skipResults(packet, out, opts, info) {
@@ -1,23 +1,25 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2024 MariaDB Corporation Ab
3
+
1
4
  'use strict';
2
5
 
3
6
  const Command = require('./command');
4
- const Errors = require('../misc/errors');
5
-
7
+ const ServerStatus = require('../const/server-status');
8
+ const RESET_COMMAND = new Uint8Array([1, 0, 0, 0, 0x1f]);
6
9
  /**
7
10
  * send a COM_RESET_CONNECTION: permits to reset a connection without re-authentication.
8
11
  * see https://mariadb.com/kb/en/library/com_reset_connection/
9
12
  */
10
13
  class Reset extends Command {
11
- constructor(resolve, reject) {
12
- super(resolve, reject);
14
+ constructor(cmdParam, resolve, reject) {
15
+ super(cmdParam, resolve, reject);
13
16
  }
14
17
 
15
18
  start(out, opts, info) {
16
- out.startPacket(this);
17
- out.writeInt8(0x1f);
18
- out.flushBuffer(true);
19
- this.emit('send_end');
19
+ if (opts.logger.query) opts.logger.query('RESET');
20
20
  this.onPacketReceive = this.readResetResponsePacket;
21
+ out.fastFlush(this, RESET_COMMAND);
22
+ this.emit('send_end');
21
23
  }
22
24
 
23
25
  /**
@@ -32,22 +34,16 @@ class Reset extends Command {
32
34
  * @param info connection info
33
35
  */
34
36
  readResetResponsePacket(packet, out, opts, info) {
35
- if (packet.peek() !== 0x00) {
36
- return this.throwNewError(
37
- 'unexpected packet',
38
- false,
39
- info,
40
- '42000',
41
- Errors.ER_RESET_BAD_PACKET
42
- );
43
- }
44
-
45
37
  packet.skip(1); //skip header
46
38
  packet.skipLengthCodedNumber(); //affected rows
47
39
  packet.skipLengthCodedNumber(); //insert ids
48
40
 
49
41
  info.status = packet.readUInt16();
50
- this.successEnd(null);
42
+ if (info.redirectRequest && (info.status & ServerStatus.STATUS_IN_TRANS) === 0) {
43
+ info.redirect(info.redirectRequest, this.successEnd.bind(this));
44
+ } else {
45
+ this.successEnd();
46
+ }
51
47
  }
52
48
  }
53
49
 
@@ -1,3 +1,6 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2024 MariaDB Corporation Ab
3
+
1
4
  'use strict';
2
5
 
3
6
  const Query = require('./query');
@@ -8,19 +11,19 @@ const { Readable } = require('stream');
8
11
  * see : https://mariadb.com/kb/en/library/com_query/
9
12
  */
10
13
  class Stream extends Query {
11
- constructor(cmdOpts, connOpts, sql, values, socket) {
14
+ constructor(cmdParam, connOpts, socket) {
12
15
  super(
13
16
  () => {},
14
17
  () => {},
15
- cmdOpts,
16
18
  connOpts,
17
- sql,
18
- values
19
+ cmdParam
19
20
  );
20
21
  this.socket = socket;
21
22
  this.inStream = new Readable({
22
23
  objectMode: true,
23
- read: () => {}
24
+ read: () => {
25
+ this.socket.resume();
26
+ }
24
27
  });
25
28
 
26
29
  this.on('fields', function (meta) {
@@ -31,14 +34,26 @@ class Stream extends Query {
31
34
  this.inStream.emit('error', err);
32
35
  });
33
36
 
37
+ this.on('close', function (err) {
38
+ this.inStream.emit('error', err);
39
+ });
40
+
34
41
  this.on('end', function (err) {
35
42
  if (err) this.inStream.emit('error', err);
43
+ this.socket.resume();
36
44
  this.inStream.push(null);
37
45
  });
46
+
47
+ this.inStream.close = function () {
48
+ this.handleNewRows = () => {};
49
+ this.socket.resume();
50
+ }.bind(this);
38
51
  }
39
52
 
40
53
  handleNewRows(row) {
41
- this.inStream.push(row);
54
+ if (!this.inStream.push(row)) {
55
+ this.socket.pause();
56
+ }
42
57
  }
43
58
  }
44
59