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,214 @@
1
+ 'use strict';
2
+
3
+ const CursorType = require('../constants/cursor');
4
+ const CommandCodes = require('../constants/commands');
5
+ const Types = require('../constants/types');
6
+ const Packet = require('../packets/packet');
7
+ const CharsetToEncoding = require('../constants/charset_encodings.js');
8
+
9
+ function isJSON(value) {
10
+ return (
11
+ Array.isArray(value) ||
12
+ value.constructor === Object ||
13
+ (typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
14
+ );
15
+ }
16
+
17
+ /**
18
+ * Converts a value to an object describing type, String/Buffer representation and length
19
+ * @param {*} value
20
+ */
21
+ function toParameter(value, encoding, timezone) {
22
+ let type = Types.VAR_STRING;
23
+ let length;
24
+ let writer = function (value) {
25
+ // eslint-disable-next-line no-invalid-this
26
+ return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
27
+ };
28
+ if (value !== null) {
29
+ switch (typeof value) {
30
+ case 'undefined':
31
+ throw new TypeError('Bind parameters must not contain undefined');
32
+
33
+ case 'number':
34
+ type = Types.DOUBLE;
35
+ length = 8;
36
+ writer = Packet.prototype.writeDouble;
37
+ break;
38
+
39
+ case 'boolean':
40
+ value = value | 0;
41
+ type = Types.TINY;
42
+ length = 1;
43
+ writer = Packet.prototype.writeInt8;
44
+ break;
45
+
46
+ case 'object':
47
+ if (Object.prototype.toString.call(value) === '[object Date]') {
48
+ type = Types.DATETIME;
49
+ length = 12;
50
+ writer = function (value) {
51
+ // eslint-disable-next-line no-invalid-this
52
+ return Packet.prototype.writeDate.call(this, value, timezone);
53
+ };
54
+ } else if (isJSON(value)) {
55
+ value = JSON.stringify(value);
56
+ type = Types.JSON;
57
+ } else if (Buffer.isBuffer(value)) {
58
+ length = Packet.lengthCodedNumberLength(value.length) + value.length;
59
+ writer = Packet.prototype.writeLengthCodedBuffer;
60
+ }
61
+ break;
62
+
63
+ default:
64
+ value = value.toString();
65
+ }
66
+ } else {
67
+ value = '';
68
+ type = Types.NULL;
69
+ }
70
+ if (!length) {
71
+ length = Packet.lengthCodedStringLength(value, encoding);
72
+ }
73
+ return { value, type, length, writer };
74
+ }
75
+
76
+ class Execute {
77
+ constructor(id, parameters, charsetNumber, timezone) {
78
+ this.id = id;
79
+ this.parameters = parameters;
80
+ this.encoding = CharsetToEncoding[charsetNumber];
81
+ this.timezone = timezone;
82
+ }
83
+
84
+ static fromPacket(packet, encoding) {
85
+ const stmtId = packet.readInt32();
86
+ const flags = packet.readInt8();
87
+ const iterationCount = packet.readInt32();
88
+
89
+ let i = packet.offset;
90
+ while (i < packet.end - 1) {
91
+ if (
92
+ (packet.buffer[i + 1] === Types.VAR_STRING ||
93
+ packet.buffer[i + 1] === Types.NULL ||
94
+ packet.buffer[i + 1] === Types.DOUBLE ||
95
+ packet.buffer[i + 1] === Types.TINY ||
96
+ packet.buffer[i + 1] === Types.DATETIME ||
97
+ packet.buffer[i + 1] === Types.JSON) &&
98
+ packet.buffer[i] === 1 &&
99
+ packet.buffer[i + 2] === 0
100
+ ) {
101
+ break;
102
+ } else {
103
+ packet.readInt8();
104
+ }
105
+ i++;
106
+ }
107
+
108
+ const types = [];
109
+
110
+ for (let i = packet.offset + 1; i < packet.end - 1; i++) {
111
+ if (
112
+ (packet.buffer[i] === Types.VAR_STRING ||
113
+ packet.buffer[i] === Types.NULL ||
114
+ packet.buffer[i] === Types.DOUBLE ||
115
+ packet.buffer[i] === Types.TINY ||
116
+ packet.buffer[i] === Types.DATETIME ||
117
+ packet.buffer[i] === Types.JSON) &&
118
+ packet.buffer[i + 1] === 0
119
+ ) {
120
+ types.push(packet.buffer[i]);
121
+ packet.skip(2);
122
+ }
123
+ }
124
+
125
+ packet.skip(1);
126
+
127
+ const values = [];
128
+ for (let i = 0; i < types.length; i++) {
129
+ if (types[i] === Types.VAR_STRING) {
130
+ values.push(packet.readLengthCodedString(encoding));
131
+ } else if (types[i] === Types.DOUBLE) {
132
+ values.push(packet.readDouble());
133
+ } else if (types[i] === Types.TINY) {
134
+ values.push(packet.readInt8());
135
+ } else if (types[i] === Types.DATETIME) {
136
+ values.push(packet.readDateTime());
137
+ } else if (types[i] === Types.JSON) {
138
+ values.push(JSON.parse(packet.readLengthCodedString(encoding)));
139
+ }
140
+ if (types[i] === Types.NULL) {
141
+ values.push(null);
142
+ }
143
+ }
144
+
145
+ return { stmtId, flags, iterationCount, values };
146
+ }
147
+
148
+ toPacket() {
149
+ // TODO: don't try to calculate packet length in advance, allocate some big buffer in advance (header + 256 bytes?)
150
+ // and copy + reallocate if not enough
151
+ // 0 + 4 - length, seqId
152
+ // 4 + 1 - COM_EXECUTE
153
+ // 5 + 4 - stmtId
154
+ // 9 + 1 - flags
155
+ // 10 + 4 - iteration-count (always 1)
156
+ let length = 14;
157
+ let parameters;
158
+ if (this.parameters && this.parameters.length > 0) {
159
+ length += Math.floor((this.parameters.length + 7) / 8);
160
+ length += 1; // new-params-bound-flag
161
+ length += 2 * this.parameters.length; // type byte for each parameter if new-params-bound-flag is set
162
+ parameters = this.parameters.map((value) =>
163
+ toParameter(value, this.encoding, this.timezone)
164
+ );
165
+ length += parameters.reduce(
166
+ (accumulator, parameter) => accumulator + parameter.length,
167
+ 0
168
+ );
169
+ }
170
+ const buffer = Buffer.allocUnsafe(length);
171
+ const packet = new Packet(0, buffer, 0, length);
172
+ packet.offset = 4;
173
+ packet.writeInt8(CommandCodes.STMT_EXECUTE);
174
+ packet.writeInt32(this.id);
175
+ packet.writeInt8(CursorType.NO_CURSOR); // flags
176
+ packet.writeInt32(1); // iteration-count, always 1
177
+ if (parameters) {
178
+ let bitmap = 0;
179
+ let bitValue = 1;
180
+ parameters.forEach((parameter) => {
181
+ if (parameter.type === Types.NULL) {
182
+ bitmap += bitValue;
183
+ }
184
+ bitValue *= 2;
185
+ if (bitValue === 256) {
186
+ packet.writeInt8(bitmap);
187
+ bitmap = 0;
188
+ bitValue = 1;
189
+ }
190
+ });
191
+ if (bitValue !== 1) {
192
+ packet.writeInt8(bitmap);
193
+ }
194
+ // TODO: explain meaning of the flag
195
+ // afaik, if set n*2 bytes with type of parameter are sent before parameters
196
+ // if not, previous execution types are used (TODO prooflink)
197
+ packet.writeInt8(1); // new-params-bound-flag
198
+ // Write parameter types
199
+ parameters.forEach((parameter) => {
200
+ packet.writeInt8(parameter.type); // field type
201
+ packet.writeInt8(0); // parameter flag
202
+ });
203
+ // Write parameter values
204
+ parameters.forEach((parameter) => {
205
+ if (parameter.type !== Types.NULL) {
206
+ parameter.writer.call(packet, parameter.value);
207
+ }
208
+ });
209
+ }
210
+ return packet;
211
+ }
212
+ }
213
+
214
+ module.exports = Execute;
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+
3
+ const Packet = require('../packets/packet');
4
+ const ClientConstants = require('../constants/client.js');
5
+
6
+ // https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
7
+
8
+ class Handshake {
9
+ constructor(args) {
10
+ this.protocolVersion = args.protocolVersion;
11
+ this.serverVersion = args.serverVersion;
12
+ this.capabilityFlags = args.capabilityFlags;
13
+ this.connectionId = args.connectionId;
14
+ this.authPluginData1 = args.authPluginData1;
15
+ this.authPluginData2 = args.authPluginData2;
16
+ this.characterSet = args.characterSet;
17
+ this.statusFlags = args.statusFlags;
18
+ this.authPluginName = args.authPluginName;
19
+ }
20
+
21
+ setScrambleData(cb) {
22
+ require('crypto').randomBytes(20, (err, data) => {
23
+ if (err) {
24
+ cb(err);
25
+ return;
26
+ }
27
+ this.authPluginData1 = data.slice(0, 8);
28
+ this.authPluginData2 = data.slice(8, 20);
29
+ cb();
30
+ });
31
+ }
32
+
33
+ toPacket(sequenceId) {
34
+ const length = 68 + Buffer.byteLength(this.serverVersion, 'utf8');
35
+ const buffer = Buffer.alloc(length + 4, 0); // zero fill, 10 bytes filler later needs to contain zeros
36
+ const packet = new Packet(sequenceId, buffer, 0, length + 4);
37
+ packet.offset = 4;
38
+ packet.writeInt8(this.protocolVersion);
39
+ packet.writeString(this.serverVersion, 'cesu8');
40
+ packet.writeInt8(0);
41
+ packet.writeInt32(this.connectionId);
42
+ packet.writeBuffer(this.authPluginData1);
43
+ packet.writeInt8(0);
44
+ const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
45
+ capabilityFlagsBuffer.writeUInt32LE(this.capabilityFlags, 0);
46
+ packet.writeBuffer(capabilityFlagsBuffer.slice(0, 2));
47
+ packet.writeInt8(this.characterSet);
48
+ packet.writeInt16(this.statusFlags);
49
+ packet.writeBuffer(capabilityFlagsBuffer.slice(2, 4));
50
+ packet.writeInt8(21); // authPluginDataLength
51
+ packet.skip(10);
52
+ packet.writeBuffer(this.authPluginData2);
53
+ packet.writeInt8(0);
54
+ packet.writeString('mysql_native_password', 'latin1');
55
+ packet.writeInt8(0);
56
+ return packet;
57
+ }
58
+
59
+ static fromPacket(packet) {
60
+ const args = {};
61
+ args.protocolVersion = packet.readInt8();
62
+ args.serverVersion = packet.readNullTerminatedString('cesu8');
63
+ args.connectionId = packet.readInt32();
64
+ args.authPluginData1 = packet.readBuffer(8);
65
+ packet.skip(1);
66
+ const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
67
+ capabilityFlagsBuffer[0] = packet.readInt8();
68
+ capabilityFlagsBuffer[1] = packet.readInt8();
69
+ if (packet.haveMoreData()) {
70
+ args.characterSet = packet.readInt8();
71
+ args.statusFlags = packet.readInt16();
72
+ // upper 2 bytes
73
+ capabilityFlagsBuffer[2] = packet.readInt8();
74
+ capabilityFlagsBuffer[3] = packet.readInt8();
75
+ args.capabilityFlags = capabilityFlagsBuffer.readUInt32LE(0);
76
+ if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
77
+ args.authPluginDataLength = packet.readInt8();
78
+ } else {
79
+ args.authPluginDataLength = 0;
80
+ packet.skip(1);
81
+ }
82
+ packet.skip(10);
83
+ } else {
84
+ args.capabilityFlags = capabilityFlagsBuffer.readUInt16LE(0);
85
+ }
86
+
87
+ const isSecureConnection =
88
+ args.capabilityFlags & ClientConstants.SECURE_CONNECTION;
89
+ if (isSecureConnection) {
90
+ const authPluginDataLength = args.authPluginDataLength;
91
+ if (authPluginDataLength === 0) {
92
+ // for Secure Password Authentication
93
+ args.authPluginDataLength = 20;
94
+ args.authPluginData2 = packet.readBuffer(12);
95
+ packet.skip(1);
96
+ } else {
97
+ // length > 0
98
+ // for Custom Auth Plugin (PLUGIN_AUTH)
99
+ const len = Math.max(13, authPluginDataLength - 8);
100
+ args.authPluginData2 = packet.readBuffer(len);
101
+ }
102
+ }
103
+
104
+ if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
105
+ args.authPluginName = packet.readNullTerminatedString('ascii');
106
+ }
107
+
108
+ return new Handshake(args);
109
+ }
110
+ }
111
+
112
+ module.exports = Handshake;
@@ -0,0 +1,144 @@
1
+ 'use strict';
2
+
3
+ const ClientConstants = require('../constants/client.js');
4
+ const CharsetToEncoding = require('../constants/charset_encodings.js');
5
+ const Packet = require('../packets/packet.js');
6
+
7
+ const auth41 = require('../auth_41.js');
8
+
9
+ class HandshakeResponse {
10
+ constructor(handshake) {
11
+ this.user = handshake.user || '';
12
+ this.database = handshake.database || '';
13
+ this.password = handshake.password || '';
14
+ this.passwordSha1 = handshake.passwordSha1;
15
+ this.authPluginData1 = handshake.authPluginData1;
16
+ this.authPluginData2 = handshake.authPluginData2;
17
+ this.compress = handshake.compress;
18
+ this.clientFlags = handshake.flags;
19
+ // TODO: pre-4.1 auth support
20
+ let authToken;
21
+ if (this.passwordSha1) {
22
+ authToken = auth41.calculateTokenFromPasswordSha(
23
+ this.passwordSha1,
24
+ this.authPluginData1,
25
+ this.authPluginData2
26
+ );
27
+ } else {
28
+ authToken = auth41.calculateToken(
29
+ this.password,
30
+ this.authPluginData1,
31
+ this.authPluginData2
32
+ );
33
+ }
34
+ this.authToken = authToken;
35
+ this.charsetNumber = handshake.charsetNumber;
36
+ this.encoding = CharsetToEncoding[handshake.charsetNumber];
37
+ this.connectAttributes = handshake.connectAttributes;
38
+ }
39
+
40
+ serializeResponse(buffer) {
41
+ const isSet = (flag) => this.clientFlags & ClientConstants[flag];
42
+ const packet = new Packet(0, buffer, 0, buffer.length);
43
+ packet.offset = 4;
44
+ packet.writeInt32(this.clientFlags);
45
+ packet.writeInt32(0); // max packet size. todo: move to config
46
+ packet.writeInt8(this.charsetNumber);
47
+ packet.skip(23);
48
+ const encoding = this.encoding;
49
+ packet.writeNullTerminatedString(this.user, encoding);
50
+ let k;
51
+ if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
52
+ packet.writeLengthCodedNumber(this.authToken.length);
53
+ packet.writeBuffer(this.authToken);
54
+ } else if (isSet('SECURE_CONNECTION')) {
55
+ packet.writeInt8(this.authToken.length);
56
+ packet.writeBuffer(this.authToken);
57
+ } else {
58
+ packet.writeBuffer(this.authToken);
59
+ packet.writeInt8(0);
60
+ }
61
+ if (isSet('CONNECT_WITH_DB')) {
62
+ packet.writeNullTerminatedString(this.database, encoding);
63
+ }
64
+ if (isSet('PLUGIN_AUTH')) {
65
+ // TODO: pass from config
66
+ packet.writeNullTerminatedString('mysql_native_password', 'latin1');
67
+ }
68
+ if (isSet('CONNECT_ATTRS')) {
69
+ const connectAttributes = this.connectAttributes || {};
70
+ const attrNames = Object.keys(connectAttributes);
71
+ let keysLength = 0;
72
+ for (k = 0; k < attrNames.length; ++k) {
73
+ keysLength += Packet.lengthCodedStringLength(attrNames[k], encoding);
74
+ keysLength += Packet.lengthCodedStringLength(
75
+ connectAttributes[attrNames[k]],
76
+ encoding
77
+ );
78
+ }
79
+ packet.writeLengthCodedNumber(keysLength);
80
+ for (k = 0; k < attrNames.length; ++k) {
81
+ packet.writeLengthCodedString(attrNames[k], encoding);
82
+ packet.writeLengthCodedString(
83
+ connectAttributes[attrNames[k]],
84
+ encoding
85
+ );
86
+ }
87
+ }
88
+ return packet;
89
+ }
90
+
91
+ toPacket() {
92
+ if (typeof this.user !== 'string') {
93
+ throw new Error('"user" connection config property must be a string');
94
+ }
95
+ if (typeof this.database !== 'string') {
96
+ throw new Error('"database" connection config property must be a string');
97
+ }
98
+ // dry run: calculate resulting packet length
99
+ const p = this.serializeResponse(Packet.MockBuffer());
100
+ return this.serializeResponse(Buffer.alloc(p.offset));
101
+ }
102
+ static fromPacket(packet) {
103
+ const args = {};
104
+ args.clientFlags = packet.readInt32();
105
+ function isSet(flag) {
106
+ return args.clientFlags & ClientConstants[flag];
107
+ }
108
+ args.maxPacketSize = packet.readInt32();
109
+ args.charsetNumber = packet.readInt8();
110
+ const encoding = CharsetToEncoding[args.charsetNumber];
111
+ args.encoding = encoding;
112
+ packet.skip(23);
113
+ args.user = packet.readNullTerminatedString(encoding);
114
+ let authTokenLength;
115
+ if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
116
+ authTokenLength = packet.readLengthCodedNumber(encoding);
117
+ args.authToken = packet.readBuffer(authTokenLength);
118
+ } else if (isSet('SECURE_CONNECTION')) {
119
+ authTokenLength = packet.readInt8();
120
+ args.authToken = packet.readBuffer(authTokenLength);
121
+ } else {
122
+ args.authToken = packet.readNullTerminatedString(encoding);
123
+ }
124
+ if (isSet('CONNECT_WITH_DB')) {
125
+ args.database = packet.readNullTerminatedString(encoding);
126
+ }
127
+ if (isSet('PLUGIN_AUTH')) {
128
+ args.authPluginName = packet.readNullTerminatedString(encoding);
129
+ }
130
+ if (isSet('CONNECT_ATTRS')) {
131
+ const keysLength = packet.readLengthCodedNumber(encoding);
132
+ const keysEnd = packet.offset + keysLength;
133
+ const attrs = {};
134
+ while (packet.offset < keysEnd) {
135
+ attrs[packet.readLengthCodedString(encoding)] =
136
+ packet.readLengthCodedString(encoding);
137
+ }
138
+ args.connectAttributes = attrs;
139
+ }
140
+ return args;
141
+ }
142
+ }
143
+
144
+ module.exports = HandshakeResponse;
@@ -0,0 +1,152 @@
1
+ // This file was modified by Oracle on June 1, 2021.
2
+ // A utility method was introduced to generate an Error instance from a
3
+ // binary server packet.
4
+ // Modifications copyright (c) 2021, Oracle and/or its affiliates.
5
+
6
+ // This file was modified by Oracle on September 21, 2021.
7
+ // The new AuthNextFactor packet is now available.
8
+ // Modifications copyright (c) 2021, Oracle and/or its affiliates.
9
+
10
+ 'use strict';
11
+
12
+ const process = require('process');
13
+
14
+ const AuthNextFactor = require('./auth_next_factor');
15
+ const AuthSwitchRequest = require('./auth_switch_request');
16
+ const AuthSwitchRequestMoreData = require('./auth_switch_request_more_data');
17
+ const AuthSwitchResponse = require('./auth_switch_response');
18
+ const BinaryRow = require('./binary_row');
19
+ const BinlogDump = require('./binlog_dump');
20
+ const ChangeUser = require('./change_user');
21
+ const CloseStatement = require('./close_statement');
22
+ const ColumnDefinition = require('./column_definition');
23
+ const Execute = require('./execute');
24
+ const Handshake = require('./handshake');
25
+ const HandshakeResponse = require('./handshake_response');
26
+ const PrepareStatement = require('./prepare_statement');
27
+ const PreparedStatementHeader = require('./prepared_statement_header');
28
+ const Query = require('./query');
29
+ const RegisterSlave = require('./register_slave');
30
+ const ResultSetHeader = require('./resultset_header');
31
+ const SSLRequest = require('./ssl_request');
32
+ const TextRow = require('./text_row');
33
+
34
+ const ctorMap = {
35
+ AuthNextFactor,
36
+ AuthSwitchRequest,
37
+ AuthSwitchRequestMoreData,
38
+ AuthSwitchResponse,
39
+ BinaryRow,
40
+ BinlogDump,
41
+ ChangeUser,
42
+ CloseStatement,
43
+ ColumnDefinition,
44
+ Execute,
45
+ Handshake,
46
+ HandshakeResponse,
47
+ PrepareStatement,
48
+ PreparedStatementHeader,
49
+ Query,
50
+ RegisterSlave,
51
+ ResultSetHeader,
52
+ SSLRequest,
53
+ TextRow,
54
+ };
55
+ Object.entries(ctorMap).forEach(([name, ctor]) => {
56
+ module.exports[name] = ctor;
57
+ // monkey-patch it to include name if debug is on
58
+ if (process.env.NODE_DEBUG) {
59
+ if (ctor.prototype.toPacket) {
60
+ const old = ctor.prototype.toPacket;
61
+ ctor.prototype.toPacket = function () {
62
+ const p = old.call(this);
63
+ p._name = name;
64
+ return p;
65
+ };
66
+ }
67
+ }
68
+ });
69
+
70
+ // simple packets:
71
+ const Packet = require('./packet');
72
+ exports.Packet = Packet;
73
+
74
+ class OK {
75
+ static toPacket(args, encoding) {
76
+ args = args || {};
77
+ const affectedRows = args.affectedRows || 0;
78
+ const insertId = args.insertId || 0;
79
+ const serverStatus = args.serverStatus || 0;
80
+ const warningCount = args.warningCount || 0;
81
+ const message = args.message || '';
82
+
83
+ let length = 9 + Packet.lengthCodedNumberLength(affectedRows);
84
+ length += Packet.lengthCodedNumberLength(insertId);
85
+
86
+ const buffer = Buffer.allocUnsafe(length);
87
+ const packet = new Packet(0, buffer, 0, length);
88
+ packet.offset = 4;
89
+ packet.writeInt8(0);
90
+ packet.writeLengthCodedNumber(affectedRows);
91
+ packet.writeLengthCodedNumber(insertId);
92
+ packet.writeInt16(serverStatus);
93
+ packet.writeInt16(warningCount);
94
+ packet.writeString(message, encoding);
95
+ packet._name = 'OK';
96
+ return packet;
97
+ }
98
+ }
99
+
100
+ exports.OK = OK;
101
+
102
+ // warnings, statusFlags
103
+ class EOF {
104
+ static toPacket(warnings, statusFlags) {
105
+ if (typeof warnings === 'undefined') {
106
+ warnings = 0;
107
+ }
108
+ if (typeof statusFlags === 'undefined') {
109
+ statusFlags = 0;
110
+ }
111
+ const packet = new Packet(0, Buffer.allocUnsafe(9), 0, 9);
112
+ packet.offset = 4;
113
+ packet.writeInt8(0xfe);
114
+ packet.writeInt16(warnings);
115
+ packet.writeInt16(statusFlags);
116
+ packet._name = 'EOF';
117
+ return packet;
118
+ }
119
+ }
120
+
121
+ exports.EOF = EOF;
122
+
123
+ class Error {
124
+ static toPacket(args, encoding) {
125
+ const length = 13 + Buffer.byteLength(args.message, 'utf8');
126
+ const packet = new Packet(0, Buffer.allocUnsafe(length), 0, length);
127
+ packet.offset = 4;
128
+ packet.writeInt8(0xff);
129
+ packet.writeInt16(args.code);
130
+ // TODO: sql state parameter
131
+ packet.writeString('#_____', encoding);
132
+ packet.writeString(args.message, encoding);
133
+ packet._name = 'Error';
134
+ return packet;
135
+ }
136
+
137
+ static fromPacket(packet) {
138
+ packet.readInt8(); // marker
139
+ const code = packet.readInt16();
140
+ packet.readString(1, 'ascii'); // sql state marker
141
+ // The SQL state of the ERR_Packet which is always 5 bytes long.
142
+ // https://dev.mysql.com/doc/dev/mysql-server/8.0.11/page_protocol_basic_dt_strings.html#sect_protocol_basic_dt_string_fix
143
+ packet.readString(5, 'ascii'); // sql state (ignore for now)
144
+ const message = packet.readNullTerminatedString('utf8');
145
+ const error = new Error();
146
+ error.message = message;
147
+ error.code = code;
148
+ return error;
149
+ }
150
+ }
151
+
152
+ exports.Error = Error;