oceanbase 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/License +19 -0
  2. package/README.md +250 -0
  3. package/index.d.ts +1 -0
  4. package/index.js +77 -0
  5. package/lib/auth_41.js +95 -0
  6. package/lib/auth_plugins/caching_sha2_password.js +108 -0
  7. package/lib/auth_plugins/caching_sha2_password.md +18 -0
  8. package/lib/auth_plugins/index.js +8 -0
  9. package/lib/auth_plugins/mysql_clear_password.js +17 -0
  10. package/lib/auth_plugins/mysql_native_password.js +34 -0
  11. package/lib/auth_plugins/sha256_password.js +68 -0
  12. package/lib/base/connection.js +978 -0
  13. package/lib/base/pool.js +237 -0
  14. package/lib/base/pool_connection.js +70 -0
  15. package/lib/commands/auth_switch.js +111 -0
  16. package/lib/commands/binlog_dump.js +109 -0
  17. package/lib/commands/change_user.js +68 -0
  18. package/lib/commands/client_handshake.js +241 -0
  19. package/lib/commands/close_statement.js +18 -0
  20. package/lib/commands/command.js +54 -0
  21. package/lib/commands/execute.js +112 -0
  22. package/lib/commands/index.js +27 -0
  23. package/lib/commands/ping.js +36 -0
  24. package/lib/commands/prepare.js +143 -0
  25. package/lib/commands/query.js +366 -0
  26. package/lib/commands/quit.js +29 -0
  27. package/lib/commands/register_slave.js +27 -0
  28. package/lib/commands/server_handshake.js +203 -0
  29. package/lib/compressed_protocol.js +127 -0
  30. package/lib/connection.js +12 -0
  31. package/lib/connection_config.js +326 -0
  32. package/lib/constants/charset_encodings.js +316 -0
  33. package/lib/constants/charsets.js +317 -0
  34. package/lib/constants/client.js +40 -0
  35. package/lib/constants/commands.js +36 -0
  36. package/lib/constants/cursor.js +8 -0
  37. package/lib/constants/encoding_charset.js +50 -0
  38. package/lib/constants/errors.js +3973 -0
  39. package/lib/constants/field_flags.js +20 -0
  40. package/lib/constants/server_status.js +44 -0
  41. package/lib/constants/session_track.js +11 -0
  42. package/lib/constants/ssl_profiles.js +11 -0
  43. package/lib/constants/types.js +64 -0
  44. package/lib/create_connection.js +10 -0
  45. package/lib/create_pool.js +10 -0
  46. package/lib/create_pool_cluster.js +9 -0
  47. package/lib/helpers.js +86 -0
  48. package/lib/packet_parser.js +195 -0
  49. package/lib/packets/auth_next_factor.js +35 -0
  50. package/lib/packets/auth_switch_request.js +38 -0
  51. package/lib/packets/auth_switch_request_more_data.js +33 -0
  52. package/lib/packets/auth_switch_response.js +30 -0
  53. package/lib/packets/binary_row.js +95 -0
  54. package/lib/packets/binlog_dump.js +33 -0
  55. package/lib/packets/binlog_query_statusvars.js +115 -0
  56. package/lib/packets/change_user.js +97 -0
  57. package/lib/packets/close_statement.js +21 -0
  58. package/lib/packets/column_definition.js +291 -0
  59. package/lib/packets/execute.js +214 -0
  60. package/lib/packets/handshake.js +112 -0
  61. package/lib/packets/handshake_response.js +144 -0
  62. package/lib/packets/index.js +152 -0
  63. package/lib/packets/packet.js +931 -0
  64. package/lib/packets/prepare_statement.js +27 -0
  65. package/lib/packets/prepared_statement_header.js +16 -0
  66. package/lib/packets/query.js +27 -0
  67. package/lib/packets/register_slave.js +46 -0
  68. package/lib/packets/resultset_header.js +124 -0
  69. package/lib/packets/ssl_request.js +25 -0
  70. package/lib/packets/text_row.js +47 -0
  71. package/lib/parsers/binary_parser.js +235 -0
  72. package/lib/parsers/parser_cache.js +68 -0
  73. package/lib/parsers/static_binary_parser.js +213 -0
  74. package/lib/parsers/static_text_parser.js +152 -0
  75. package/lib/parsers/string.js +50 -0
  76. package/lib/parsers/text_parser.js +214 -0
  77. package/lib/pool.js +12 -0
  78. package/lib/pool_cluster.js +369 -0
  79. package/lib/pool_config.js +30 -0
  80. package/lib/pool_connection.js +12 -0
  81. package/lib/promise/connection.js +222 -0
  82. package/lib/promise/inherit_events.js +27 -0
  83. package/lib/promise/make_done_cb.js +19 -0
  84. package/lib/promise/pool.js +112 -0
  85. package/lib/promise/pool_cluster.js +54 -0
  86. package/lib/promise/pool_connection.js +19 -0
  87. package/lib/promise/prepared_statement_info.js +32 -0
  88. package/lib/results_stream.js +38 -0
  89. package/lib/server.js +37 -0
  90. package/package.json +80 -0
  91. package/promise.d.ts +131 -0
  92. package/promise.js +202 -0
  93. package/typings/mysql/LICENSE.txt +15 -0
  94. package/typings/mysql/index.d.ts +95 -0
  95. package/typings/mysql/info.txt +1 -0
  96. package/typings/mysql/lib/Auth.d.ts +30 -0
  97. package/typings/mysql/lib/Connection.d.ts +453 -0
  98. package/typings/mysql/lib/Pool.d.ts +69 -0
  99. package/typings/mysql/lib/PoolCluster.d.ts +90 -0
  100. package/typings/mysql/lib/PoolConnection.d.ts +10 -0
  101. package/typings/mysql/lib/Server.d.ts +11 -0
  102. package/typings/mysql/lib/constants/CharsetToEncoding.d.ts +8 -0
  103. package/typings/mysql/lib/constants/Charsets.d.ts +326 -0
  104. package/typings/mysql/lib/constants/Types.d.ts +70 -0
  105. package/typings/mysql/lib/constants/index.d.ts +5 -0
  106. package/typings/mysql/lib/parsers/ParserCache.d.ts +4 -0
  107. package/typings/mysql/lib/parsers/index.d.ts +18 -0
  108. package/typings/mysql/lib/parsers/typeCast.d.ts +54 -0
  109. package/typings/mysql/lib/protocol/packets/Field.d.ts +10 -0
  110. package/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +27 -0
  111. package/typings/mysql/lib/protocol/packets/OkPacket.d.ts +23 -0
  112. package/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts +13 -0
  113. package/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts +18 -0
  114. package/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts +9 -0
  115. package/typings/mysql/lib/protocol/packets/index.d.ts +28 -0
  116. package/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts +6 -0
  117. package/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts +9 -0
  118. package/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts +40 -0
  119. package/typings/mysql/lib/protocol/sequences/Prepare.d.ts +65 -0
  120. package/typings/mysql/lib/protocol/sequences/Query.d.ts +170 -0
  121. package/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts +40 -0
  122. package/typings/mysql/lib/protocol/sequences/Sequence.d.ts +5 -0
  123. package/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts +21 -0
  124. package/typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts +21 -0
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ // connection mixins
4
+ // implementation of http://dev.mysql.com/doc/internals/en/compression.html
5
+
6
+ const zlib = require('zlib');
7
+ const PacketParser = require('./packet_parser.js');
8
+
9
+ function handleCompressedPacket(packet) {
10
+ // eslint-disable-next-line consistent-this, no-invalid-this
11
+ const connection = this;
12
+ const deflatedLength = packet.readInt24();
13
+ const body = packet.readBuffer();
14
+
15
+ if (deflatedLength !== 0) {
16
+ connection.inflateQueue.push((task) => {
17
+ zlib.inflate(body, (err, data) => {
18
+ if (err) {
19
+ connection._handleNetworkError(err);
20
+ return;
21
+ }
22
+ connection._bumpCompressedSequenceId(packet.numPackets);
23
+ connection._inflatedPacketsParser.execute(data);
24
+ task.done();
25
+ });
26
+ });
27
+ } else {
28
+ connection.inflateQueue.push((task) => {
29
+ connection._bumpCompressedSequenceId(packet.numPackets);
30
+ connection._inflatedPacketsParser.execute(body);
31
+ task.done();
32
+ });
33
+ }
34
+ }
35
+
36
+ function writeCompressed(buffer) {
37
+ // http://dev.mysql.com/doc/internals/en/example-several-mysql-packets.html
38
+ // note: sending a MySQL Packet of the size 2^24−5 to 2^24−1 via compression
39
+ // leads to at least one extra compressed packet.
40
+ // (this is because "length of the packet before compression" need to fit
41
+ // into 3 byte unsigned int. "length of the packet before compression" includes
42
+ // 4 byte packet header, hence 2^24−5)
43
+ const MAX_COMPRESSED_LENGTH = 16777210;
44
+ let start;
45
+ if (buffer.length > MAX_COMPRESSED_LENGTH) {
46
+ for (start = 0; start < buffer.length; start += MAX_COMPRESSED_LENGTH) {
47
+ writeCompressed.call(
48
+ // eslint-disable-next-line no-invalid-this
49
+ this,
50
+ buffer.slice(start, start + MAX_COMPRESSED_LENGTH)
51
+ );
52
+ }
53
+ return;
54
+ }
55
+
56
+ // eslint-disable-next-line no-invalid-this, consistent-this
57
+ const connection = this;
58
+
59
+ let packetLen = buffer.length;
60
+ const compressHeader = Buffer.allocUnsafe(7);
61
+
62
+ // seqqueue is used here because zlib async execution is routed via thread pool
63
+ // internally and when we have multiple compressed packets arriving we need
64
+ // to assemble uncompressed result sequentially
65
+ (function (seqId) {
66
+ connection.deflateQueue.push((task) => {
67
+ zlib.deflate(buffer, (err, compressed) => {
68
+ if (err) {
69
+ connection._handleFatalError(err);
70
+ return;
71
+ }
72
+ let compressedLength = compressed.length;
73
+
74
+ if (compressedLength < packetLen) {
75
+ compressHeader.writeUInt8(compressedLength & 0xff, 0);
76
+ compressHeader.writeUInt16LE(compressedLength >> 8, 1);
77
+ compressHeader.writeUInt8(seqId, 3);
78
+ compressHeader.writeUInt8(packetLen & 0xff, 4);
79
+ compressHeader.writeUInt16LE(packetLen >> 8, 5);
80
+ connection.writeUncompressed(compressHeader);
81
+ connection.writeUncompressed(compressed);
82
+ } else {
83
+ // http://dev.mysql.com/doc/internals/en/uncompressed-payload.html
84
+ // To send an uncompressed payload:
85
+ // - set length of payload before compression to 0
86
+ // - the compressed payload contains the uncompressed payload instead.
87
+ compressedLength = packetLen;
88
+ packetLen = 0;
89
+ compressHeader.writeUInt8(compressedLength & 0xff, 0);
90
+ compressHeader.writeUInt16LE(compressedLength >> 8, 1);
91
+ compressHeader.writeUInt8(seqId, 3);
92
+ compressHeader.writeUInt8(packetLen & 0xff, 4);
93
+ compressHeader.writeUInt16LE(packetLen >> 8, 5);
94
+ connection.writeUncompressed(compressHeader);
95
+ connection.writeUncompressed(buffer);
96
+ }
97
+ task.done();
98
+ });
99
+ });
100
+ })(connection.compressedSequenceId);
101
+ connection._bumpCompressedSequenceId(1);
102
+ }
103
+
104
+ function enableCompression(connection) {
105
+ connection._lastWrittenPacketId = 0;
106
+ connection._lastReceivedPacketId = 0;
107
+
108
+ connection._handleCompressedPacket = handleCompressedPacket;
109
+ connection._inflatedPacketsParser = new PacketParser((p) => {
110
+ connection.handlePacket(p);
111
+ }, 4);
112
+ connection._inflatedPacketsParser._lastPacket = 0;
113
+ connection.packetParser = new PacketParser((packet) => {
114
+ connection._handleCompressedPacket(packet);
115
+ }, 7);
116
+
117
+ connection.writeUncompressed = connection.write;
118
+ connection.write = writeCompressed;
119
+
120
+ const seqqueue = require('seq-queue');
121
+ connection.inflateQueue = seqqueue.createQueue();
122
+ connection.deflateQueue = seqqueue.createQueue();
123
+ }
124
+
125
+ module.exports = {
126
+ enableCompression: enableCompression,
127
+ };
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const BaseConnection = require('./base/connection.js');
4
+
5
+ class Connection extends BaseConnection {
6
+ promise(promiseImpl) {
7
+ const PromiseConnection = require('./promise/connection.js');
8
+ return new PromiseConnection(this, promiseImpl);
9
+ }
10
+ }
11
+
12
+ module.exports = Connection;
@@ -0,0 +1,326 @@
1
+ // This file was modified by Oracle on September 21, 2021.
2
+ // New connection options for additional authentication factors were
3
+ // introduced.
4
+ // Multi-factor authentication capability is now enabled if one of these
5
+ // options is used.
6
+ // Modifications copyright (c) 2021, Oracle and/or its affiliates.
7
+
8
+ 'use strict';
9
+
10
+ const { URL } = require('url');
11
+ const ClientConstants = require('./constants/client');
12
+ const Charsets = require('./constants/charsets');
13
+ const { version } = require('../package.json');
14
+ let SSLProfiles = null;
15
+
16
+ const validOptions = {
17
+ authPlugins: 1,
18
+ authSwitchHandler: 1,
19
+ bigNumberStrings: 1,
20
+ charset: 1,
21
+ charsetNumber: 1,
22
+ compress: 1,
23
+ connectAttributes: 1,
24
+ connectTimeout: 1,
25
+ database: 1,
26
+ dateStrings: 1,
27
+ debug: 1,
28
+ decimalNumbers: 1,
29
+ enableKeepAlive: 1,
30
+ flags: 1,
31
+ host: 1,
32
+ insecureAuth: 1,
33
+ infileStreamFactory: 1,
34
+ isServer: 1,
35
+ keepAliveInitialDelay: 1,
36
+ localAddress: 1,
37
+ maxPreparedStatements: 1,
38
+ mode: 1,
39
+ multipleStatements: 1,
40
+ namedPlaceholders: 1,
41
+ nestTables: 1,
42
+ password: 1,
43
+ // with multi-factor authentication, the main password (used for the first
44
+ // authentication factor) can be provided via password1
45
+ password1: 1,
46
+ password2: 1,
47
+ password3: 1,
48
+ passwordSha1: 1,
49
+ pool: 1,
50
+ port: 1,
51
+ queryFormat: 1,
52
+ rowsAsArray: 1,
53
+ socketPath: 1,
54
+ ssl: 1,
55
+ stream: 1,
56
+ stringifyObjects: 1,
57
+ supportBigNumbers: 1,
58
+ timezone: 1,
59
+ trace: 1,
60
+ typeCast: 1,
61
+ uri: 1,
62
+ user: 1,
63
+ disableEval: 1,
64
+ // These options are used for Pool
65
+ connectionLimit: 1,
66
+ maxIdle: 1,
67
+ idleTimeout: 1,
68
+ Promise: 1,
69
+ queueLimit: 1,
70
+ waitForConnections: 1,
71
+ jsonStrings: 1,
72
+ gracefulEnd: 1,
73
+ tenant: 1,
74
+ cluster: 1,
75
+ };
76
+
77
+ class ConnectionConfig {
78
+ constructor(options) {
79
+ if (typeof options === 'string') {
80
+ options = ConnectionConfig.parseUrl(options);
81
+ } else if (options && options.uri) {
82
+ const uriOptions = ConnectionConfig.parseUrl(options.uri);
83
+ for (const key in uriOptions) {
84
+ if (!Object.prototype.hasOwnProperty.call(uriOptions, key)) continue;
85
+ if (options[key]) continue;
86
+ options[key] = uriOptions[key];
87
+ }
88
+ }
89
+ for (const key in options) {
90
+ if (!Object.prototype.hasOwnProperty.call(options, key)) continue;
91
+ if (validOptions[key] !== 1) {
92
+ // REVIEW: Should this be emitted somehow?
93
+ // eslint-disable-next-line no-console
94
+ console.error(
95
+ `Ignoring invalid configuration option passed to Connection: ${key}. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection`
96
+ );
97
+ }
98
+ }
99
+ this.isServer = options.isServer;
100
+ this.stream = options.stream;
101
+ this.host = options.host || 'localhost';
102
+ this.port =
103
+ (typeof options.port === 'string'
104
+ ? parseInt(options.port, 10)
105
+ : options.port) || 3306;
106
+ this.localAddress = options.localAddress;
107
+ this.socketPath = options.socketPath;
108
+ // OceanBase support: tenant and cluster fields
109
+ this.tenant = options.tenant || undefined;
110
+ this.cluster = options.cluster || undefined;
111
+ // Format username as username@tenant#cluster for OceanBase
112
+ let user = options.user || undefined;
113
+ if (user && (this.tenant || this.cluster)) {
114
+ // Check if username already contains @ or # (already formatted)
115
+ // If not, format it as username@tenant#cluster
116
+ if (user.indexOf('@') === -1 && user.indexOf('#') === -1) {
117
+ let formattedUser = user;
118
+ if (this.tenant) {
119
+ formattedUser = `${formattedUser}@${this.tenant}`;
120
+ }
121
+ if (this.cluster) {
122
+ formattedUser = `${formattedUser}#${this.cluster}`;
123
+ }
124
+ this.user = formattedUser;
125
+ } else {
126
+ // Username already contains @ or #, use as-is
127
+ this.user = user;
128
+ }
129
+ } else {
130
+ this.user = user;
131
+ }
132
+ // for the purpose of multi-factor authentication, or not, the main
133
+ // password (used for the 1st authentication factor) can also be
134
+ // provided via the "password1" option
135
+ this.password = options.password || options.password1 || undefined;
136
+ this.password2 = options.password2 || undefined;
137
+ this.password3 = options.password3 || undefined;
138
+ this.passwordSha1 = options.passwordSha1 || undefined;
139
+ this.database = options.database;
140
+ this.connectTimeout = isNaN(options.connectTimeout)
141
+ ? 10 * 1000
142
+ : options.connectTimeout;
143
+ this.insecureAuth = options.insecureAuth || false;
144
+ this.infileStreamFactory = options.infileStreamFactory || undefined;
145
+ this.supportBigNumbers = options.supportBigNumbers || false;
146
+ this.bigNumberStrings = options.bigNumberStrings || false;
147
+ this.decimalNumbers = options.decimalNumbers || false;
148
+ this.dateStrings = options.dateStrings || false;
149
+ this.debug = options.debug;
150
+ this.trace = options.trace !== false;
151
+ this.stringifyObjects = options.stringifyObjects || false;
152
+ this.enableKeepAlive = options.enableKeepAlive !== false;
153
+ this.keepAliveInitialDelay = options.keepAliveInitialDelay;
154
+ if (
155
+ options.timezone &&
156
+ !/^(?:local|Z|[ +-]\d\d:\d\d)$/.test(options.timezone)
157
+ ) {
158
+ // strictly supports timezones specified by mysqljs/mysql:
159
+ // https://github.com/mysqljs/mysql#user-content-connection-options
160
+ // eslint-disable-next-line no-console
161
+ console.error(
162
+ `Ignoring invalid timezone passed to Connection: ${options.timezone}. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection`
163
+ );
164
+ // SqlStrings falls back to UTC on invalid timezone
165
+ this.timezone = 'Z';
166
+ } else {
167
+ this.timezone = options.timezone || 'local';
168
+ }
169
+ this.queryFormat = options.queryFormat;
170
+ this.pool = options.pool || undefined;
171
+ this.ssl =
172
+ typeof options.ssl === 'string'
173
+ ? ConnectionConfig.getSSLProfile(options.ssl)
174
+ : options.ssl || false;
175
+ this.multipleStatements = options.multipleStatements || false;
176
+ this.rowsAsArray = options.rowsAsArray || false;
177
+ this.namedPlaceholders = options.namedPlaceholders || false;
178
+ this.nestTables =
179
+ options.nestTables === undefined ? undefined : options.nestTables;
180
+ this.typeCast = options.typeCast === undefined ? true : options.typeCast;
181
+ this.disableEval = Boolean(options.disableEval);
182
+ if (this.timezone[0] === ' ') {
183
+ // "+" is a url encoded char for space so it
184
+ // gets translated to space when giving a
185
+ // connection string..
186
+ this.timezone = `+${this.timezone.slice(1)}`;
187
+ }
188
+ if (this.ssl) {
189
+ if (typeof this.ssl !== 'object') {
190
+ throw new TypeError(
191
+ `SSL profile must be an object, instead it's a ${typeof this.ssl}`
192
+ );
193
+ }
194
+ // Default rejectUnauthorized to true
195
+ this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
196
+ }
197
+ this.maxPacketSize = 0;
198
+ this.charsetNumber = options.charset
199
+ ? ConnectionConfig.getCharsetNumber(options.charset)
200
+ : options.charsetNumber || Charsets.UTF8MB4_UNICODE_CI;
201
+ this.compress = options.compress || false;
202
+ this.authPlugins = options.authPlugins;
203
+ this.authSwitchHandler = options.authSwitchHandler;
204
+ this.clientFlags = ConnectionConfig.mergeFlags(
205
+ ConnectionConfig.getDefaultFlags(options),
206
+ options.flags || ''
207
+ );
208
+ // Default connection attributes
209
+ // https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html
210
+ const defaultConnectAttributes = {
211
+ _client_name: 'Node-MySQL-2',
212
+ _client_version: version,
213
+ };
214
+ this.connectAttributes = {
215
+ ...defaultConnectAttributes,
216
+ ...(options.connectAttributes || {}),
217
+ };
218
+ this.maxPreparedStatements = options.maxPreparedStatements || 16000;
219
+ this.jsonStrings = options.jsonStrings || false;
220
+ this.gracefulEnd = options.gracefulEnd || false;
221
+ this.mode = options.mode || 'mysql';
222
+ }
223
+
224
+ static mergeFlags(default_flags, user_flags) {
225
+ let flags = 0x0,
226
+ i;
227
+ if (!Array.isArray(user_flags)) {
228
+ user_flags = String(user_flags || '')
229
+ .toUpperCase()
230
+ .split(/\s*,+\s*/);
231
+ }
232
+ // add default flags unless "blacklisted"
233
+ for (i in default_flags) {
234
+ if (user_flags.indexOf(`-${default_flags[i]}`) >= 0) {
235
+ continue;
236
+ }
237
+ flags |= ClientConstants[default_flags[i]] || 0x0;
238
+ }
239
+ // add user flags unless already already added
240
+ for (i in user_flags) {
241
+ if (user_flags[i][0] === '-') {
242
+ continue;
243
+ }
244
+ if (default_flags.indexOf(user_flags[i]) >= 0) {
245
+ continue;
246
+ }
247
+ flags |= ClientConstants[user_flags[i]] || 0x0;
248
+ }
249
+ return flags;
250
+ }
251
+
252
+ static getDefaultFlags(options) {
253
+ const defaultFlags = [
254
+ 'LONG_PASSWORD',
255
+ 'FOUND_ROWS',
256
+ 'LONG_FLAG',
257
+ 'CONNECT_WITH_DB',
258
+ 'ODBC',
259
+ 'LOCAL_FILES',
260
+ 'IGNORE_SPACE',
261
+ 'PROTOCOL_41',
262
+ 'IGNORE_SIGPIPE',
263
+ 'TRANSACTIONS',
264
+ 'RESERVED',
265
+ 'SECURE_CONNECTION',
266
+ 'MULTI_RESULTS',
267
+ 'TRANSACTIONS',
268
+ 'SESSION_TRACK',
269
+ 'CONNECT_ATTRS',
270
+ ];
271
+ if (options && options.multipleStatements) {
272
+ defaultFlags.push('MULTI_STATEMENTS');
273
+ }
274
+ if (options && options.mode === 'oracle') {
275
+ defaultFlags.push('ORACLE_MODE');
276
+ }
277
+ defaultFlags.push('PLUGIN_AUTH');
278
+ defaultFlags.push('PLUGIN_AUTH_LENENC_CLIENT_DATA');
279
+
280
+ return defaultFlags;
281
+ }
282
+
283
+ static getCharsetNumber(charset) {
284
+ const num = Charsets[charset.toUpperCase()];
285
+ if (num === undefined) {
286
+ throw new TypeError(`Unknown charset '${charset}'`);
287
+ }
288
+ return num;
289
+ }
290
+
291
+ static getSSLProfile(name) {
292
+ if (!SSLProfiles) {
293
+ SSLProfiles = require('./constants/ssl_profiles.js');
294
+ }
295
+ const ssl = SSLProfiles[name];
296
+ if (ssl === undefined) {
297
+ throw new TypeError(`Unknown SSL profile '${name}'`);
298
+ }
299
+ return ssl;
300
+ }
301
+
302
+ static parseUrl(url) {
303
+ const parsedUrl = new URL(url);
304
+ const options = {
305
+ host: decodeURIComponent(parsedUrl.hostname),
306
+ port: parseInt(parsedUrl.port, 10),
307
+ database: decodeURIComponent(parsedUrl.pathname.slice(1)),
308
+ user: decodeURIComponent(parsedUrl.username),
309
+ password: decodeURIComponent(parsedUrl.password),
310
+ };
311
+ parsedUrl.searchParams.forEach((value, key) => {
312
+ try {
313
+ // Try to parse this as a JSON expression first
314
+ options[key] = JSON.parse(value);
315
+ } catch (err) {
316
+ // Otherwise assume it is a plain string
317
+ options[key] = value;
318
+ }
319
+ });
320
+ // OceanBase support: parse tenant and cluster from URL query params
321
+ // The username formatting will be handled in constructor
322
+ return options;
323
+ }
324
+ }
325
+
326
+ module.exports = ConnectionConfig;