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.
- package/License +19 -0
- package/README.md +250 -0
- package/index.d.ts +1 -0
- package/index.js +77 -0
- package/lib/auth_41.js +95 -0
- package/lib/auth_plugins/caching_sha2_password.js +108 -0
- package/lib/auth_plugins/caching_sha2_password.md +18 -0
- package/lib/auth_plugins/index.js +8 -0
- package/lib/auth_plugins/mysql_clear_password.js +17 -0
- package/lib/auth_plugins/mysql_native_password.js +34 -0
- package/lib/auth_plugins/sha256_password.js +68 -0
- package/lib/base/connection.js +978 -0
- package/lib/base/pool.js +237 -0
- package/lib/base/pool_connection.js +70 -0
- package/lib/commands/auth_switch.js +111 -0
- package/lib/commands/binlog_dump.js +109 -0
- package/lib/commands/change_user.js +68 -0
- package/lib/commands/client_handshake.js +241 -0
- package/lib/commands/close_statement.js +18 -0
- package/lib/commands/command.js +54 -0
- package/lib/commands/execute.js +112 -0
- package/lib/commands/index.js +27 -0
- package/lib/commands/ping.js +36 -0
- package/lib/commands/prepare.js +143 -0
- package/lib/commands/query.js +366 -0
- package/lib/commands/quit.js +29 -0
- package/lib/commands/register_slave.js +27 -0
- package/lib/commands/server_handshake.js +203 -0
- package/lib/compressed_protocol.js +127 -0
- package/lib/connection.js +12 -0
- package/lib/connection_config.js +326 -0
- package/lib/constants/charset_encodings.js +316 -0
- package/lib/constants/charsets.js +317 -0
- package/lib/constants/client.js +40 -0
- package/lib/constants/commands.js +36 -0
- package/lib/constants/cursor.js +8 -0
- package/lib/constants/encoding_charset.js +50 -0
- package/lib/constants/errors.js +3973 -0
- package/lib/constants/field_flags.js +20 -0
- package/lib/constants/server_status.js +44 -0
- package/lib/constants/session_track.js +11 -0
- package/lib/constants/ssl_profiles.js +11 -0
- package/lib/constants/types.js +64 -0
- package/lib/create_connection.js +10 -0
- package/lib/create_pool.js +10 -0
- package/lib/create_pool_cluster.js +9 -0
- package/lib/helpers.js +86 -0
- package/lib/packet_parser.js +195 -0
- package/lib/packets/auth_next_factor.js +35 -0
- package/lib/packets/auth_switch_request.js +38 -0
- package/lib/packets/auth_switch_request_more_data.js +33 -0
- package/lib/packets/auth_switch_response.js +30 -0
- package/lib/packets/binary_row.js +95 -0
- package/lib/packets/binlog_dump.js +33 -0
- package/lib/packets/binlog_query_statusvars.js +115 -0
- package/lib/packets/change_user.js +97 -0
- package/lib/packets/close_statement.js +21 -0
- package/lib/packets/column_definition.js +291 -0
- package/lib/packets/execute.js +214 -0
- package/lib/packets/handshake.js +112 -0
- package/lib/packets/handshake_response.js +144 -0
- package/lib/packets/index.js +152 -0
- package/lib/packets/packet.js +931 -0
- package/lib/packets/prepare_statement.js +27 -0
- package/lib/packets/prepared_statement_header.js +16 -0
- package/lib/packets/query.js +27 -0
- package/lib/packets/register_slave.js +46 -0
- package/lib/packets/resultset_header.js +124 -0
- package/lib/packets/ssl_request.js +25 -0
- package/lib/packets/text_row.js +47 -0
- package/lib/parsers/binary_parser.js +235 -0
- package/lib/parsers/parser_cache.js +68 -0
- package/lib/parsers/static_binary_parser.js +213 -0
- package/lib/parsers/static_text_parser.js +152 -0
- package/lib/parsers/string.js +50 -0
- package/lib/parsers/text_parser.js +214 -0
- package/lib/pool.js +12 -0
- package/lib/pool_cluster.js +369 -0
- package/lib/pool_config.js +30 -0
- package/lib/pool_connection.js +12 -0
- package/lib/promise/connection.js +222 -0
- package/lib/promise/inherit_events.js +27 -0
- package/lib/promise/make_done_cb.js +19 -0
- package/lib/promise/pool.js +112 -0
- package/lib/promise/pool_cluster.js +54 -0
- package/lib/promise/pool_connection.js +19 -0
- package/lib/promise/prepared_statement_info.js +32 -0
- package/lib/results_stream.js +38 -0
- package/lib/server.js +37 -0
- package/package.json +80 -0
- package/promise.d.ts +131 -0
- package/promise.js +202 -0
- package/typings/mysql/LICENSE.txt +15 -0
- package/typings/mysql/index.d.ts +95 -0
- package/typings/mysql/info.txt +1 -0
- package/typings/mysql/lib/Auth.d.ts +30 -0
- package/typings/mysql/lib/Connection.d.ts +453 -0
- package/typings/mysql/lib/Pool.d.ts +69 -0
- package/typings/mysql/lib/PoolCluster.d.ts +90 -0
- package/typings/mysql/lib/PoolConnection.d.ts +10 -0
- package/typings/mysql/lib/Server.d.ts +11 -0
- package/typings/mysql/lib/constants/CharsetToEncoding.d.ts +8 -0
- package/typings/mysql/lib/constants/Charsets.d.ts +326 -0
- package/typings/mysql/lib/constants/Types.d.ts +70 -0
- package/typings/mysql/lib/constants/index.d.ts +5 -0
- package/typings/mysql/lib/parsers/ParserCache.d.ts +4 -0
- package/typings/mysql/lib/parsers/index.d.ts +18 -0
- package/typings/mysql/lib/parsers/typeCast.d.ts +54 -0
- package/typings/mysql/lib/protocol/packets/Field.d.ts +10 -0
- package/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +27 -0
- package/typings/mysql/lib/protocol/packets/OkPacket.d.ts +23 -0
- package/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts +13 -0
- package/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts +18 -0
- package/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts +9 -0
- package/typings/mysql/lib/protocol/packets/index.d.ts +28 -0
- package/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts +6 -0
- package/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts +9 -0
- package/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts +40 -0
- package/typings/mysql/lib/protocol/sequences/Prepare.d.ts +65 -0
- package/typings/mysql/lib/protocol/sequences/Query.d.ts +170 -0
- package/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts +40 -0
- package/typings/mysql/lib/protocol/sequences/Sequence.d.ts +5 -0
- package/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts +21 -0
- 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;
|