node-server-dev 3.1.5 → 3.1.7
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/dist/cjs/browser.js +1 -1
- package/dist/cjs/getAllRouter/index.js +1 -1
- package/dist/cjs/hash/index.js +1 -1
- package/dist/cjs/id/index.js +1 -1
- package/dist/cjs/id/random.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/jwt/index.js +1 -1
- package/dist/cjs/mac/index.js +1 -1
- package/dist/cjs/package/mysql2/License +19 -0
- package/dist/cjs/package/mysql2/README.md +114 -0
- package/dist/cjs/package/mysql2/index.d.ts +1 -0
- package/dist/cjs/package/mysql2/index.js +77 -0
- package/dist/cjs/package/mysql2/lib/auth_41.js +95 -0
- package/dist/cjs/package/mysql2/lib/auth_plugins/caching_sha2_password.js +108 -0
- package/dist/cjs/package/mysql2/lib/auth_plugins/caching_sha2_password.md +18 -0
- package/dist/cjs/package/mysql2/lib/auth_plugins/index.js +8 -0
- package/dist/cjs/package/mysql2/lib/auth_plugins/mysql_clear_password.js +17 -0
- package/dist/cjs/package/mysql2/lib/auth_plugins/mysql_native_password.js +34 -0
- package/dist/cjs/package/mysql2/lib/auth_plugins/sha256_password.js +59 -0
- package/dist/cjs/package/mysql2/lib/base/connection.js +945 -0
- package/dist/cjs/package/mysql2/lib/base/pool.js +233 -0
- package/dist/cjs/package/mysql2/lib/base/pool_connection.js +63 -0
- package/dist/cjs/package/mysql2/lib/commands/auth_switch.js +111 -0
- package/dist/cjs/package/mysql2/lib/commands/binlog_dump.js +109 -0
- package/dist/cjs/package/mysql2/lib/commands/change_user.js +68 -0
- package/dist/cjs/package/mysql2/lib/commands/client_handshake.js +241 -0
- package/dist/cjs/package/mysql2/lib/commands/close_statement.js +18 -0
- package/dist/cjs/package/mysql2/lib/commands/command.js +54 -0
- package/dist/cjs/package/mysql2/lib/commands/execute.js +112 -0
- package/dist/cjs/package/mysql2/lib/commands/index.js +27 -0
- package/dist/cjs/package/mysql2/lib/commands/ping.js +36 -0
- package/dist/cjs/package/mysql2/lib/commands/prepare.js +143 -0
- package/dist/cjs/package/mysql2/lib/commands/query.js +329 -0
- package/dist/cjs/package/mysql2/lib/commands/quit.js +29 -0
- package/dist/cjs/package/mysql2/lib/commands/register_slave.js +27 -0
- package/dist/cjs/package/mysql2/lib/commands/server_handshake.js +203 -0
- package/dist/cjs/package/mysql2/lib/compressed_protocol.js +127 -0
- package/dist/cjs/package/mysql2/lib/connection.js +12 -0
- package/dist/cjs/package/mysql2/lib/connection_config.js +292 -0
- package/dist/cjs/package/mysql2/lib/constants/charset_encodings.js +316 -0
- package/dist/cjs/package/mysql2/lib/constants/charsets.js +317 -0
- package/dist/cjs/package/mysql2/lib/constants/client.js +39 -0
- package/dist/cjs/package/mysql2/lib/constants/commands.js +36 -0
- package/dist/cjs/package/mysql2/lib/constants/cursor.js +8 -0
- package/dist/cjs/package/mysql2/lib/constants/encoding_charset.js +49 -0
- package/dist/cjs/package/mysql2/lib/constants/errors.js +3973 -0
- package/dist/cjs/package/mysql2/lib/constants/field_flags.js +20 -0
- package/dist/cjs/package/mysql2/lib/constants/server_status.js +44 -0
- package/dist/cjs/package/mysql2/lib/constants/session_track.js +11 -0
- package/dist/cjs/package/mysql2/lib/constants/ssl_profiles.js +11 -0
- package/dist/cjs/package/mysql2/lib/constants/types.js +64 -0
- package/dist/cjs/package/mysql2/lib/create_connection.js +10 -0
- package/dist/cjs/package/mysql2/lib/create_pool.js +10 -0
- package/dist/cjs/package/mysql2/lib/create_pool_cluster.js +9 -0
- package/dist/cjs/package/mysql2/lib/helpers.js +86 -0
- package/dist/cjs/package/mysql2/lib/packet_parser.js +195 -0
- package/dist/cjs/package/mysql2/lib/packets/auth_next_factor.js +35 -0
- package/dist/cjs/package/mysql2/lib/packets/auth_switch_request.js +38 -0
- package/dist/cjs/package/mysql2/lib/packets/auth_switch_request_more_data.js +33 -0
- package/dist/cjs/package/mysql2/lib/packets/auth_switch_response.js +30 -0
- package/dist/cjs/package/mysql2/lib/packets/binary_row.js +95 -0
- package/dist/cjs/package/mysql2/lib/packets/binlog_dump.js +33 -0
- package/dist/cjs/package/mysql2/lib/packets/binlog_query_statusvars.js +115 -0
- package/dist/cjs/package/mysql2/lib/packets/change_user.js +97 -0
- package/dist/cjs/package/mysql2/lib/packets/close_statement.js +21 -0
- package/dist/cjs/package/mysql2/lib/packets/column_definition.js +291 -0
- package/dist/cjs/package/mysql2/lib/packets/execute.js +214 -0
- package/dist/cjs/package/mysql2/lib/packets/handshake.js +112 -0
- package/dist/cjs/package/mysql2/lib/packets/handshake_response.js +144 -0
- package/dist/cjs/package/mysql2/lib/packets/index.js +152 -0
- package/dist/cjs/package/mysql2/lib/packets/packet.js +931 -0
- package/dist/cjs/package/mysql2/lib/packets/prepare_statement.js +27 -0
- package/dist/cjs/package/mysql2/lib/packets/prepared_statement_header.js +16 -0
- package/dist/cjs/package/mysql2/lib/packets/query.js +27 -0
- package/dist/cjs/package/mysql2/lib/packets/register_slave.js +46 -0
- package/dist/cjs/package/mysql2/lib/packets/resultset_header.js +118 -0
- package/dist/cjs/package/mysql2/lib/packets/ssl_request.js +25 -0
- package/dist/cjs/package/mysql2/lib/packets/text_row.js +47 -0
- package/dist/cjs/package/mysql2/lib/parsers/binary_parser.js +231 -0
- package/dist/cjs/package/mysql2/lib/parsers/parser_cache.js +66 -0
- package/dist/cjs/package/mysql2/lib/parsers/static_binary_parser.js +211 -0
- package/dist/cjs/package/mysql2/lib/parsers/static_text_parser.js +152 -0
- package/dist/cjs/package/mysql2/lib/parsers/string.js +50 -0
- package/dist/cjs/package/mysql2/lib/parsers/text_parser.js +214 -0
- package/dist/cjs/package/mysql2/lib/pool.js +12 -0
- package/dist/cjs/package/mysql2/lib/pool_cluster.js +369 -0
- package/dist/cjs/package/mysql2/lib/pool_config.js +30 -0
- package/dist/cjs/package/mysql2/lib/pool_connection.js +12 -0
- package/dist/cjs/package/mysql2/lib/promise/connection.js +222 -0
- package/dist/cjs/package/mysql2/lib/promise/inherit_events.js +27 -0
- package/dist/cjs/package/mysql2/lib/promise/make_done_cb.js +19 -0
- package/dist/cjs/package/mysql2/lib/promise/pool.js +112 -0
- package/dist/cjs/package/mysql2/lib/promise/pool_cluster.js +54 -0
- package/dist/cjs/package/mysql2/lib/promise/pool_connection.js +19 -0
- package/dist/cjs/package/mysql2/lib/promise/prepared_statement_info.js +32 -0
- package/dist/cjs/package/mysql2/lib/results_stream.js +38 -0
- package/dist/cjs/package/mysql2/lib/server.js +37 -0
- package/dist/cjs/package/mysql2/package.json +80 -0
- package/dist/cjs/package/mysql2/promise.d.ts +131 -0
- package/dist/cjs/package/mysql2/promise.js +202 -0
- package/dist/cjs/package/mysql2/typings/mysql/LICENSE.txt +15 -0
- package/dist/cjs/package/mysql2/typings/mysql/index.d.ts +95 -0
- package/dist/cjs/package/mysql2/typings/mysql/info.txt +1 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/Auth.d.ts +30 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/Connection.d.ts +428 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/Pool.d.ts +69 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/PoolCluster.d.ts +90 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/PoolConnection.d.ts +10 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/Server.d.ts +11 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/constants/CharsetToEncoding.d.ts +8 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/constants/Charsets.d.ts +326 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/constants/Types.d.ts +70 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/constants/index.d.ts +5 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/parsers/ParserCache.d.ts +4 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/parsers/index.d.ts +18 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/parsers/typeCast.d.ts +54 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/Field.d.ts +10 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +27 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/OkPacket.d.ts +23 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts +13 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts +18 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts +9 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/index.d.ts +28 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts +6 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts +9 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts +40 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/Prepare.d.ts +65 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/Query.d.ts +170 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts +40 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/Sequence.d.ts +5 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts +21 -0
- package/dist/cjs/package/mysql2/typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts +21 -0
- package/dist/cjs/package/mysql_backup/index.js +69 -0
- package/dist/cjs/package/mysql_backup/promise.js +187 -0
- package/dist/cjs/server.d.ts +1 -1
- package/dist/cjs/server.d.ts.map +1 -1
- package/dist/cjs/server.js +1 -1
- package/dist/cjs/start.js +1 -1
- package/dist/cjs/update.js +1 -1
- package/dist/esm/browser.js +1 -1
- package/dist/esm/getAllRouter/index.js +1 -1
- package/dist/esm/hash/index.js +1 -1
- package/dist/esm/id/index.js +1 -1
- package/dist/esm/id/random.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/jwt/index.js +1 -1
- package/dist/esm/mac/index.js +1 -1
- package/dist/esm/package/mysql2/License +19 -0
- package/dist/esm/package/mysql2/README.md +114 -0
- package/dist/esm/package/mysql2/index.d.ts +1 -0
- package/dist/esm/package/mysql2/index.js +77 -0
- package/dist/esm/package/mysql2/lib/auth_41.js +95 -0
- package/dist/esm/package/mysql2/lib/auth_plugins/caching_sha2_password.js +108 -0
- package/dist/esm/package/mysql2/lib/auth_plugins/caching_sha2_password.md +18 -0
- package/dist/esm/package/mysql2/lib/auth_plugins/index.js +8 -0
- package/dist/esm/package/mysql2/lib/auth_plugins/mysql_clear_password.js +17 -0
- package/dist/esm/package/mysql2/lib/auth_plugins/mysql_native_password.js +34 -0
- package/dist/esm/package/mysql2/lib/auth_plugins/sha256_password.js +59 -0
- package/dist/esm/package/mysql2/lib/base/connection.js +945 -0
- package/dist/esm/package/mysql2/lib/base/pool.js +233 -0
- package/dist/esm/package/mysql2/lib/base/pool_connection.js +63 -0
- package/dist/esm/package/mysql2/lib/commands/auth_switch.js +111 -0
- package/dist/esm/package/mysql2/lib/commands/binlog_dump.js +109 -0
- package/dist/esm/package/mysql2/lib/commands/change_user.js +68 -0
- package/dist/esm/package/mysql2/lib/commands/client_handshake.js +241 -0
- package/dist/esm/package/mysql2/lib/commands/close_statement.js +18 -0
- package/dist/esm/package/mysql2/lib/commands/command.js +54 -0
- package/dist/esm/package/mysql2/lib/commands/execute.js +112 -0
- package/dist/esm/package/mysql2/lib/commands/index.js +27 -0
- package/dist/esm/package/mysql2/lib/commands/ping.js +36 -0
- package/dist/esm/package/mysql2/lib/commands/prepare.js +143 -0
- package/dist/esm/package/mysql2/lib/commands/query.js +329 -0
- package/dist/esm/package/mysql2/lib/commands/quit.js +29 -0
- package/dist/esm/package/mysql2/lib/commands/register_slave.js +27 -0
- package/dist/esm/package/mysql2/lib/commands/server_handshake.js +203 -0
- package/dist/esm/package/mysql2/lib/compressed_protocol.js +127 -0
- package/dist/esm/package/mysql2/lib/connection.js +12 -0
- package/dist/esm/package/mysql2/lib/connection_config.js +292 -0
- package/dist/esm/package/mysql2/lib/constants/charset_encodings.js +316 -0
- package/dist/esm/package/mysql2/lib/constants/charsets.js +317 -0
- package/dist/esm/package/mysql2/lib/constants/client.js +39 -0
- package/dist/esm/package/mysql2/lib/constants/commands.js +36 -0
- package/dist/esm/package/mysql2/lib/constants/cursor.js +8 -0
- package/dist/esm/package/mysql2/lib/constants/encoding_charset.js +49 -0
- package/dist/esm/package/mysql2/lib/constants/errors.js +3973 -0
- package/dist/esm/package/mysql2/lib/constants/field_flags.js +20 -0
- package/dist/esm/package/mysql2/lib/constants/server_status.js +44 -0
- package/dist/esm/package/mysql2/lib/constants/session_track.js +11 -0
- package/dist/esm/package/mysql2/lib/constants/ssl_profiles.js +11 -0
- package/dist/esm/package/mysql2/lib/constants/types.js +64 -0
- package/dist/esm/package/mysql2/lib/create_connection.js +10 -0
- package/dist/esm/package/mysql2/lib/create_pool.js +10 -0
- package/dist/esm/package/mysql2/lib/create_pool_cluster.js +9 -0
- package/dist/esm/package/mysql2/lib/helpers.js +86 -0
- package/dist/esm/package/mysql2/lib/packet_parser.js +195 -0
- package/dist/esm/package/mysql2/lib/packets/auth_next_factor.js +35 -0
- package/dist/esm/package/mysql2/lib/packets/auth_switch_request.js +38 -0
- package/dist/esm/package/mysql2/lib/packets/auth_switch_request_more_data.js +33 -0
- package/dist/esm/package/mysql2/lib/packets/auth_switch_response.js +30 -0
- package/dist/esm/package/mysql2/lib/packets/binary_row.js +95 -0
- package/dist/esm/package/mysql2/lib/packets/binlog_dump.js +33 -0
- package/dist/esm/package/mysql2/lib/packets/binlog_query_statusvars.js +115 -0
- package/dist/esm/package/mysql2/lib/packets/change_user.js +97 -0
- package/dist/esm/package/mysql2/lib/packets/close_statement.js +21 -0
- package/dist/esm/package/mysql2/lib/packets/column_definition.js +291 -0
- package/dist/esm/package/mysql2/lib/packets/execute.js +214 -0
- package/dist/esm/package/mysql2/lib/packets/handshake.js +112 -0
- package/dist/esm/package/mysql2/lib/packets/handshake_response.js +144 -0
- package/dist/esm/package/mysql2/lib/packets/index.js +152 -0
- package/dist/esm/package/mysql2/lib/packets/packet.js +931 -0
- package/dist/esm/package/mysql2/lib/packets/prepare_statement.js +27 -0
- package/dist/esm/package/mysql2/lib/packets/prepared_statement_header.js +16 -0
- package/dist/esm/package/mysql2/lib/packets/query.js +27 -0
- package/dist/esm/package/mysql2/lib/packets/register_slave.js +46 -0
- package/dist/esm/package/mysql2/lib/packets/resultset_header.js +118 -0
- package/dist/esm/package/mysql2/lib/packets/ssl_request.js +25 -0
- package/dist/esm/package/mysql2/lib/packets/text_row.js +47 -0
- package/dist/esm/package/mysql2/lib/parsers/binary_parser.js +231 -0
- package/dist/esm/package/mysql2/lib/parsers/parser_cache.js +66 -0
- package/dist/esm/package/mysql2/lib/parsers/static_binary_parser.js +211 -0
- package/dist/esm/package/mysql2/lib/parsers/static_text_parser.js +152 -0
- package/dist/esm/package/mysql2/lib/parsers/string.js +50 -0
- package/dist/esm/package/mysql2/lib/parsers/text_parser.js +214 -0
- package/dist/esm/package/mysql2/lib/pool.js +12 -0
- package/dist/esm/package/mysql2/lib/pool_cluster.js +369 -0
- package/dist/esm/package/mysql2/lib/pool_config.js +30 -0
- package/dist/esm/package/mysql2/lib/pool_connection.js +12 -0
- package/dist/esm/package/mysql2/lib/promise/connection.js +222 -0
- package/dist/esm/package/mysql2/lib/promise/inherit_events.js +27 -0
- package/dist/esm/package/mysql2/lib/promise/make_done_cb.js +19 -0
- package/dist/esm/package/mysql2/lib/promise/pool.js +112 -0
- package/dist/esm/package/mysql2/lib/promise/pool_cluster.js +54 -0
- package/dist/esm/package/mysql2/lib/promise/pool_connection.js +19 -0
- package/dist/esm/package/mysql2/lib/promise/prepared_statement_info.js +32 -0
- package/dist/esm/package/mysql2/lib/results_stream.js +38 -0
- package/dist/esm/package/mysql2/lib/server.js +37 -0
- package/dist/esm/package/mysql2/package.json +80 -0
- package/dist/esm/package/mysql2/promise.d.ts +131 -0
- package/dist/esm/package/mysql2/promise.js +202 -0
- package/dist/esm/package/mysql2/typings/mysql/LICENSE.txt +15 -0
- package/dist/esm/package/mysql2/typings/mysql/index.d.ts +95 -0
- package/dist/esm/package/mysql2/typings/mysql/info.txt +1 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/Auth.d.ts +30 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/Connection.d.ts +428 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/Pool.d.ts +69 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/PoolCluster.d.ts +90 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/PoolConnection.d.ts +10 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/Server.d.ts +11 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/constants/CharsetToEncoding.d.ts +8 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/constants/Charsets.d.ts +326 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/constants/Types.d.ts +70 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/constants/index.d.ts +5 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/parsers/ParserCache.d.ts +4 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/parsers/index.d.ts +18 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/parsers/typeCast.d.ts +54 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/Field.d.ts +10 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +27 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/OkPacket.d.ts +23 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts +13 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts +18 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts +9 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/index.d.ts +28 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts +6 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts +9 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts +40 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/Prepare.d.ts +65 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/Query.d.ts +170 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts +40 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/Sequence.d.ts +5 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts +21 -0
- package/dist/esm/package/mysql2/typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts +21 -0
- package/dist/esm/package/mysql_backup/index.js +69 -0
- package/dist/esm/package/mysql_backup/promise.js +187 -0
- package/dist/esm/server.d.ts +1 -1
- package/dist/esm/server.d.ts.map +1 -1
- package/dist/esm/server.js +1 -1
- package/dist/esm/start.js +1 -1
- package/dist/esm/update.js +1 -1
- package/package.json +3 -4
@@ -0,0 +1,945 @@
|
|
1
|
+
// This file was modified by Oracle on June 1, 2021.
|
2
|
+
// The changes involve new logic to handle an additional ERR Packet sent by
|
3
|
+
// the MySQL server when the connection is closed unexpectedly.
|
4
|
+
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
5
|
+
|
6
|
+
// This file was modified by Oracle on June 17, 2021.
|
7
|
+
// The changes involve logic to ensure the socket connection is closed when
|
8
|
+
// there is a fatal error.
|
9
|
+
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
10
|
+
|
11
|
+
// This file was modified by Oracle on September 21, 2021.
|
12
|
+
// The changes involve passing additional authentication factor passwords
|
13
|
+
// to the ChangeUser Command instance.
|
14
|
+
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
15
|
+
|
16
|
+
'use strict';
|
17
|
+
|
18
|
+
const Net = require('net');
|
19
|
+
const Tls = require('tls');
|
20
|
+
const Timers = require('timers');
|
21
|
+
const EventEmitter = require('events').EventEmitter;
|
22
|
+
const Readable = require('stream').Readable;
|
23
|
+
const Queue = require('denque');
|
24
|
+
const SqlString = require('sqlstring');
|
25
|
+
const { createLRU } = require('lru.min');
|
26
|
+
const PacketParser = require('../packet_parser.js');
|
27
|
+
const Packets = require('../packets/index.js');
|
28
|
+
const Commands = require('../commands/index.js');
|
29
|
+
const ConnectionConfig = require('../connection_config.js');
|
30
|
+
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
31
|
+
|
32
|
+
let _connectionId = 0;
|
33
|
+
|
34
|
+
let convertNamedPlaceholders = null;
|
35
|
+
|
36
|
+
class BaseConnection extends EventEmitter {
|
37
|
+
constructor(opts) {
|
38
|
+
super();
|
39
|
+
this.config = opts.config;
|
40
|
+
// TODO: fill defaults
|
41
|
+
// if no params, connect to /var/lib/mysql/mysql.sock ( /tmp/mysql.sock on OSX )
|
42
|
+
// if host is given, connect to host:3306
|
43
|
+
// TODO: use `/usr/local/mysql/bin/mysql_config --socket` output? as default socketPath
|
44
|
+
// if there is no host/port and no socketPath parameters?
|
45
|
+
if (!opts.config.stream) {
|
46
|
+
if (opts.config.socketPath) {
|
47
|
+
this.stream = Net.connect(opts.config.socketPath);
|
48
|
+
} else {
|
49
|
+
this.stream = Net.connect(opts.config.port, opts.config.host);
|
50
|
+
|
51
|
+
// Optionally enable keep-alive on the socket.
|
52
|
+
if (this.config.enableKeepAlive) {
|
53
|
+
this.stream.on('connect', () => {
|
54
|
+
this.stream.setKeepAlive(true, this.config.keepAliveInitialDelay);
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
// Enable TCP_NODELAY flag. This is needed so that the network packets
|
59
|
+
// are sent immediately to the server
|
60
|
+
this.stream.setNoDelay(true);
|
61
|
+
}
|
62
|
+
// if stream is a function, treat it as "stream agent / factory"
|
63
|
+
} else if (typeof opts.config.stream === 'function') {
|
64
|
+
this.stream = opts.config.stream(opts);
|
65
|
+
} else {
|
66
|
+
this.stream = opts.config.stream;
|
67
|
+
}
|
68
|
+
|
69
|
+
this._internalId = _connectionId++;
|
70
|
+
this._commands = new Queue();
|
71
|
+
this._command = null;
|
72
|
+
this._paused = false;
|
73
|
+
this._paused_packets = new Queue();
|
74
|
+
this._statements = createLRU({
|
75
|
+
max: this.config.maxPreparedStatements,
|
76
|
+
onEviction: function (_, statement) {
|
77
|
+
statement.close();
|
78
|
+
},
|
79
|
+
});
|
80
|
+
this.serverCapabilityFlags = 0;
|
81
|
+
this.authorized = false;
|
82
|
+
this.sequenceId = 0;
|
83
|
+
this.compressedSequenceId = 0;
|
84
|
+
this.threadId = null;
|
85
|
+
this._handshakePacket = null;
|
86
|
+
this._fatalError = null;
|
87
|
+
this._protocolError = null;
|
88
|
+
this._outOfOrderPackets = [];
|
89
|
+
this.clientEncoding = CharsetToEncoding[this.config.charsetNumber];
|
90
|
+
this.stream.on('error', this._handleNetworkError.bind(this));
|
91
|
+
// see https://gist.github.com/khoomeister/4985691#use-that-instead-of-bind
|
92
|
+
this.packetParser = new PacketParser((p) => {
|
93
|
+
this.handlePacket(p);
|
94
|
+
});
|
95
|
+
this.stream.on('data', (data) => {
|
96
|
+
if (this.connectTimeout) {
|
97
|
+
Timers.clearTimeout(this.connectTimeout);
|
98
|
+
this.connectTimeout = null;
|
99
|
+
}
|
100
|
+
this.packetParser.execute(data);
|
101
|
+
});
|
102
|
+
this.stream.on('end', () => {
|
103
|
+
// emit the end event so that the pooled connection can close the connection
|
104
|
+
this.emit('end');
|
105
|
+
});
|
106
|
+
this.stream.on('close', () => {
|
107
|
+
// we need to set this flag everywhere where we want connection to close
|
108
|
+
if (this._closing) {
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
if (!this._protocolError) {
|
112
|
+
// no particular error message before disconnect
|
113
|
+
this._protocolError = new Error(
|
114
|
+
'Connection lost: The server closed the connection.'
|
115
|
+
);
|
116
|
+
this._protocolError.fatal = true;
|
117
|
+
this._protocolError.code = 'PROTOCOL_CONNECTION_LOST';
|
118
|
+
}
|
119
|
+
this._notifyError(this._protocolError);
|
120
|
+
});
|
121
|
+
let handshakeCommand;
|
122
|
+
if (!this.config.isServer) {
|
123
|
+
handshakeCommand = new Commands.ClientHandshake(this.config.clientFlags);
|
124
|
+
handshakeCommand.on('end', () => {
|
125
|
+
// this happens when handshake finishes early either because there was
|
126
|
+
// some fatal error or the server sent an error packet instead of
|
127
|
+
// an hello packet (for example, 'Too many connections' error)
|
128
|
+
if (
|
129
|
+
!handshakeCommand.handshake ||
|
130
|
+
this._fatalError ||
|
131
|
+
this._protocolError
|
132
|
+
) {
|
133
|
+
return;
|
134
|
+
}
|
135
|
+
this._handshakePacket = handshakeCommand.handshake;
|
136
|
+
this.threadId = handshakeCommand.handshake.connectionId;
|
137
|
+
this.emit('connect', handshakeCommand.handshake);
|
138
|
+
});
|
139
|
+
handshakeCommand.on('error', (err) => {
|
140
|
+
this._closing = true;
|
141
|
+
this._notifyError(err);
|
142
|
+
});
|
143
|
+
this.addCommand(handshakeCommand);
|
144
|
+
}
|
145
|
+
// in case there was no initial handshake but we need to read sting, assume it utf-8
|
146
|
+
// most common example: "Too many connections" error ( packet is sent immediately on connection attempt, we don't know server encoding yet)
|
147
|
+
// will be overwritten with actual encoding value as soon as server handshake packet is received
|
148
|
+
this.serverEncoding = 'utf8';
|
149
|
+
if (this.config.connectTimeout) {
|
150
|
+
const timeoutHandler = this._handleTimeoutError.bind(this);
|
151
|
+
this.connectTimeout = Timers.setTimeout(
|
152
|
+
timeoutHandler,
|
153
|
+
this.config.connectTimeout
|
154
|
+
);
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
_addCommandClosedState(cmd) {
|
159
|
+
const err = new Error(
|
160
|
+
"Can't add new command when connection is in closed state"
|
161
|
+
);
|
162
|
+
err.fatal = true;
|
163
|
+
if (cmd.onResult) {
|
164
|
+
cmd.onResult(err);
|
165
|
+
} else {
|
166
|
+
this.emit('error', err);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
_handleFatalError(err) {
|
171
|
+
err.fatal = true;
|
172
|
+
// stop receiving packets
|
173
|
+
this.stream.removeAllListeners('data');
|
174
|
+
this.addCommand = this._addCommandClosedState;
|
175
|
+
this.write = () => {
|
176
|
+
this.emit('error', new Error("Can't write in closed state"));
|
177
|
+
};
|
178
|
+
this._notifyError(err);
|
179
|
+
this._fatalError = err;
|
180
|
+
}
|
181
|
+
|
182
|
+
_handleNetworkError(err) {
|
183
|
+
if (this.connectTimeout) {
|
184
|
+
Timers.clearTimeout(this.connectTimeout);
|
185
|
+
this.connectTimeout = null;
|
186
|
+
}
|
187
|
+
// Do not throw an error when a connection ends with a RST,ACK packet
|
188
|
+
if (err.code === 'ECONNRESET' && this._closing) {
|
189
|
+
return;
|
190
|
+
}
|
191
|
+
this._handleFatalError(err);
|
192
|
+
}
|
193
|
+
|
194
|
+
_handleTimeoutError() {
|
195
|
+
if (this.connectTimeout) {
|
196
|
+
Timers.clearTimeout(this.connectTimeout);
|
197
|
+
this.connectTimeout = null;
|
198
|
+
}
|
199
|
+
this.stream.destroy && this.stream.destroy();
|
200
|
+
const err = new Error('connect ETIMEDOUT');
|
201
|
+
err.errorno = 'ETIMEDOUT';
|
202
|
+
err.code = 'ETIMEDOUT';
|
203
|
+
err.syscall = 'connect';
|
204
|
+
this._handleNetworkError(err);
|
205
|
+
}
|
206
|
+
|
207
|
+
// notify all commands in the queue and bubble error as connection "error"
|
208
|
+
// called on stream error or unexpected termination
|
209
|
+
_notifyError(err) {
|
210
|
+
if (this.connectTimeout) {
|
211
|
+
Timers.clearTimeout(this.connectTimeout);
|
212
|
+
this.connectTimeout = null;
|
213
|
+
}
|
214
|
+
// prevent from emitting 'PROTOCOL_CONNECTION_LOST' after EPIPE or ECONNRESET
|
215
|
+
if (this._fatalError) {
|
216
|
+
return;
|
217
|
+
}
|
218
|
+
let command;
|
219
|
+
// if there is no active command, notify connection
|
220
|
+
// if there are commands and all of them have callbacks, pass error via callback
|
221
|
+
let bubbleErrorToConnection = !this._command;
|
222
|
+
if (this._command && this._command.onResult) {
|
223
|
+
this._command.onResult(err);
|
224
|
+
this._command = null;
|
225
|
+
// connection handshake is special because we allow it to be implicit
|
226
|
+
// if error happened during handshake, but there are others commands in queue
|
227
|
+
// then bubble error to other commands and not to connection
|
228
|
+
} else if (
|
229
|
+
!(
|
230
|
+
this._command &&
|
231
|
+
this._command.constructor === Commands.ClientHandshake &&
|
232
|
+
this._commands.length > 0
|
233
|
+
)
|
234
|
+
) {
|
235
|
+
bubbleErrorToConnection = true;
|
236
|
+
}
|
237
|
+
while ((command = this._commands.shift())) {
|
238
|
+
if (command.onResult) {
|
239
|
+
command.onResult(err);
|
240
|
+
} else {
|
241
|
+
bubbleErrorToConnection = true;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
// notify connection if some comands in the queue did not have callbacks
|
245
|
+
// or if this is pool connection ( so it can be removed from pool )
|
246
|
+
if (bubbleErrorToConnection || this._pool) {
|
247
|
+
this.emit('error', err);
|
248
|
+
}
|
249
|
+
// close connection after emitting the event in case of a fatal error
|
250
|
+
if (err.fatal) {
|
251
|
+
this.close();
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
write(buffer) {
|
256
|
+
const result = this.stream.write(buffer, (err) => {
|
257
|
+
if (err) {
|
258
|
+
this._handleNetworkError(err);
|
259
|
+
}
|
260
|
+
});
|
261
|
+
|
262
|
+
if (!result) {
|
263
|
+
this.stream.emit('pause');
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
// http://dev.mysql.com/doc/internals/en/sequence-id.html
|
268
|
+
//
|
269
|
+
// The sequence-id is incremented with each packet and may wrap around.
|
270
|
+
// It starts at 0 and is reset to 0 when a new command
|
271
|
+
// begins in the Command Phase.
|
272
|
+
// http://dev.mysql.com/doc/internals/en/example-several-mysql-packets.html
|
273
|
+
_resetSequenceId() {
|
274
|
+
this.sequenceId = 0;
|
275
|
+
this.compressedSequenceId = 0;
|
276
|
+
}
|
277
|
+
|
278
|
+
_bumpCompressedSequenceId(numPackets) {
|
279
|
+
this.compressedSequenceId += numPackets;
|
280
|
+
this.compressedSequenceId %= 256;
|
281
|
+
}
|
282
|
+
|
283
|
+
_bumpSequenceId(numPackets) {
|
284
|
+
this.sequenceId += numPackets;
|
285
|
+
this.sequenceId %= 256;
|
286
|
+
}
|
287
|
+
|
288
|
+
writePacket(packet) {
|
289
|
+
const MAX_PACKET_LENGTH = 16777215;
|
290
|
+
const length = packet.length();
|
291
|
+
let chunk, offset, header;
|
292
|
+
if (length < MAX_PACKET_LENGTH) {
|
293
|
+
packet.writeHeader(this.sequenceId);
|
294
|
+
if (this.config.debug) {
|
295
|
+
console.log(
|
296
|
+
`${this._internalId} ${this.connectionId} <== ${this._command._commandName}#${this._command.stateName()}(${[this.sequenceId, packet._name, packet.length()].join(',')})`
|
297
|
+
);
|
298
|
+
console.log(
|
299
|
+
`${this._internalId} ${this.connectionId} <== ${packet.buffer.toString('hex')}`
|
300
|
+
);
|
301
|
+
}
|
302
|
+
this._bumpSequenceId(1);
|
303
|
+
this.write(packet.buffer);
|
304
|
+
} else {
|
305
|
+
if (this.config.debug) {
|
306
|
+
console.log(
|
307
|
+
`${this._internalId} ${this.connectionId} <== Writing large packet, raw content not written:`
|
308
|
+
);
|
309
|
+
console.log(
|
310
|
+
`${this._internalId} ${this.connectionId} <== ${this._command._commandName}#${this._command.stateName()}(${[this.sequenceId, packet._name, packet.length()].join(',')})`
|
311
|
+
);
|
312
|
+
}
|
313
|
+
for (offset = 4; offset < 4 + length; offset += MAX_PACKET_LENGTH) {
|
314
|
+
chunk = packet.buffer.slice(offset, offset + MAX_PACKET_LENGTH);
|
315
|
+
if (chunk.length === MAX_PACKET_LENGTH) {
|
316
|
+
header = Buffer.from([0xff, 0xff, 0xff, this.sequenceId]);
|
317
|
+
} else {
|
318
|
+
header = Buffer.from([
|
319
|
+
chunk.length & 0xff,
|
320
|
+
(chunk.length >> 8) & 0xff,
|
321
|
+
(chunk.length >> 16) & 0xff,
|
322
|
+
this.sequenceId,
|
323
|
+
]);
|
324
|
+
}
|
325
|
+
this._bumpSequenceId(1);
|
326
|
+
this.write(header);
|
327
|
+
this.write(chunk);
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
// 0.11+ environment
|
333
|
+
startTLS(onSecure) {
|
334
|
+
if (this.config.debug) {
|
335
|
+
console.log('Upgrading connection to TLS');
|
336
|
+
}
|
337
|
+
const secureContext = Tls.createSecureContext({
|
338
|
+
ca: this.config.ssl.ca,
|
339
|
+
cert: this.config.ssl.cert,
|
340
|
+
ciphers: this.config.ssl.ciphers,
|
341
|
+
key: this.config.ssl.key,
|
342
|
+
passphrase: this.config.ssl.passphrase,
|
343
|
+
minVersion: this.config.ssl.minVersion,
|
344
|
+
maxVersion: this.config.ssl.maxVersion,
|
345
|
+
});
|
346
|
+
const rejectUnauthorized = this.config.ssl.rejectUnauthorized;
|
347
|
+
const verifyIdentity = this.config.ssl.verifyIdentity;
|
348
|
+
const servername = this.config.host;
|
349
|
+
|
350
|
+
let secureEstablished = false;
|
351
|
+
this.stream.removeAllListeners('data');
|
352
|
+
const secureSocket = Tls.connect(
|
353
|
+
{
|
354
|
+
rejectUnauthorized,
|
355
|
+
requestCert: rejectUnauthorized,
|
356
|
+
checkServerIdentity: verifyIdentity
|
357
|
+
? Tls.checkServerIdentity
|
358
|
+
: function () {
|
359
|
+
return undefined;
|
360
|
+
},
|
361
|
+
secureContext,
|
362
|
+
isServer: false,
|
363
|
+
socket: this.stream,
|
364
|
+
servername,
|
365
|
+
},
|
366
|
+
() => {
|
367
|
+
secureEstablished = true;
|
368
|
+
if (rejectUnauthorized) {
|
369
|
+
if (typeof servername === 'string' && verifyIdentity) {
|
370
|
+
const cert = secureSocket.getPeerCertificate(true);
|
371
|
+
const serverIdentityCheckError = Tls.checkServerIdentity(
|
372
|
+
servername,
|
373
|
+
cert
|
374
|
+
);
|
375
|
+
if (serverIdentityCheckError) {
|
376
|
+
onSecure(serverIdentityCheckError);
|
377
|
+
return;
|
378
|
+
}
|
379
|
+
}
|
380
|
+
}
|
381
|
+
onSecure();
|
382
|
+
}
|
383
|
+
);
|
384
|
+
// error handler for secure socket
|
385
|
+
secureSocket.on('error', (err) => {
|
386
|
+
if (secureEstablished) {
|
387
|
+
this._handleNetworkError(err);
|
388
|
+
} else {
|
389
|
+
onSecure(err);
|
390
|
+
}
|
391
|
+
});
|
392
|
+
secureSocket.on('data', (data) => {
|
393
|
+
this.packetParser.execute(data);
|
394
|
+
});
|
395
|
+
this.write = (buffer) => secureSocket.write(buffer);
|
396
|
+
}
|
397
|
+
|
398
|
+
protocolError(message, code) {
|
399
|
+
// Starting with MySQL 8.0.24, if the client closes the connection
|
400
|
+
// unexpectedly, the server will send a last ERR Packet, which we can
|
401
|
+
// safely ignore.
|
402
|
+
// https://dev.mysql.com/worklog/task/?id=12999
|
403
|
+
if (this._closing) {
|
404
|
+
return;
|
405
|
+
}
|
406
|
+
|
407
|
+
const err = new Error(message);
|
408
|
+
err.fatal = true;
|
409
|
+
err.code = code || 'PROTOCOL_ERROR';
|
410
|
+
this.emit('error', err);
|
411
|
+
}
|
412
|
+
|
413
|
+
get fatalError() {
|
414
|
+
return this._fatalError;
|
415
|
+
}
|
416
|
+
|
417
|
+
handlePacket(packet) {
|
418
|
+
if (this._paused) {
|
419
|
+
this._paused_packets.push(packet);
|
420
|
+
return;
|
421
|
+
}
|
422
|
+
if (this.config.debug) {
|
423
|
+
if (packet) {
|
424
|
+
console.log(
|
425
|
+
` raw: ${packet.buffer
|
426
|
+
.slice(packet.offset, packet.offset + packet.length())
|
427
|
+
.toString('hex')}`
|
428
|
+
);
|
429
|
+
console.trace();
|
430
|
+
const commandName = this._command
|
431
|
+
? this._command._commandName
|
432
|
+
: '(no command)';
|
433
|
+
const stateName = this._command
|
434
|
+
? this._command.stateName()
|
435
|
+
: '(no command)';
|
436
|
+
console.log(
|
437
|
+
`${this._internalId} ${this.connectionId} ==> ${commandName}#${stateName}(${[packet.sequenceId, packet.type(), packet.length()].join(',')})`
|
438
|
+
);
|
439
|
+
}
|
440
|
+
}
|
441
|
+
if (!this._command) {
|
442
|
+
const marker = packet.peekByte();
|
443
|
+
// If it's an Err Packet, we should use it.
|
444
|
+
if (marker === 0xff) {
|
445
|
+
const error = Packets.Error.fromPacket(packet);
|
446
|
+
this.protocolError(error.message, error.code);
|
447
|
+
} else {
|
448
|
+
// Otherwise, it means it's some other unexpected packet.
|
449
|
+
this.protocolError(
|
450
|
+
'Unexpected packet while no commands in the queue',
|
451
|
+
'PROTOCOL_UNEXPECTED_PACKET'
|
452
|
+
);
|
453
|
+
}
|
454
|
+
this.close();
|
455
|
+
return;
|
456
|
+
}
|
457
|
+
if (packet) {
|
458
|
+
// Note: when server closes connection due to inactivity, Err packet ER_CLIENT_INTERACTION_TIMEOUT from MySQL 8.0.24, sequenceId will be 0
|
459
|
+
if (this.sequenceId !== packet.sequenceId) {
|
460
|
+
const err = new Error(
|
461
|
+
`Warning: got packets out of order. Expected ${this.sequenceId} but received ${packet.sequenceId}`
|
462
|
+
);
|
463
|
+
err.expected = this.sequenceId;
|
464
|
+
err.received = packet.sequenceId;
|
465
|
+
this.emit('warn', err); // REVIEW
|
466
|
+
console.error(err.message);
|
467
|
+
}
|
468
|
+
this._bumpSequenceId(packet.numPackets);
|
469
|
+
}
|
470
|
+
try {
|
471
|
+
if (this._fatalError) {
|
472
|
+
// skip remaining packets after client is in the error state
|
473
|
+
return;
|
474
|
+
}
|
475
|
+
const done = this._command.execute(packet, this);
|
476
|
+
if (done) {
|
477
|
+
this._command = this._commands.shift();
|
478
|
+
if (this._command) {
|
479
|
+
this.sequenceId = 0;
|
480
|
+
this.compressedSequenceId = 0;
|
481
|
+
this.handlePacket();
|
482
|
+
}
|
483
|
+
}
|
484
|
+
} catch (err) {
|
485
|
+
this._handleFatalError(err);
|
486
|
+
this.stream.destroy();
|
487
|
+
}
|
488
|
+
}
|
489
|
+
|
490
|
+
addCommand(cmd) {
|
491
|
+
// this.compressedSequenceId = 0;
|
492
|
+
// this.sequenceId = 0;
|
493
|
+
if (this.config.debug) {
|
494
|
+
const commandName = cmd.constructor.name;
|
495
|
+
console.log(`Add command: ${commandName}`);
|
496
|
+
cmd._commandName = commandName;
|
497
|
+
}
|
498
|
+
if (!this._command) {
|
499
|
+
this._command = cmd;
|
500
|
+
this.handlePacket();
|
501
|
+
} else {
|
502
|
+
this._commands.push(cmd);
|
503
|
+
}
|
504
|
+
return cmd;
|
505
|
+
}
|
506
|
+
|
507
|
+
format(sql, values) {
|
508
|
+
if (typeof this.config.queryFormat === 'function') {
|
509
|
+
return this.config.queryFormat.call(
|
510
|
+
this,
|
511
|
+
sql,
|
512
|
+
values,
|
513
|
+
this.config.timezone
|
514
|
+
);
|
515
|
+
}
|
516
|
+
const opts = {
|
517
|
+
sql: sql,
|
518
|
+
values: values,
|
519
|
+
};
|
520
|
+
this._resolveNamedPlaceholders(opts);
|
521
|
+
return SqlString.format(
|
522
|
+
opts.sql,
|
523
|
+
opts.values,
|
524
|
+
this.config.stringifyObjects,
|
525
|
+
this.config.timezone
|
526
|
+
);
|
527
|
+
}
|
528
|
+
|
529
|
+
escape(value) {
|
530
|
+
return SqlString.escape(value, false, this.config.timezone);
|
531
|
+
}
|
532
|
+
|
533
|
+
escapeId(value) {
|
534
|
+
return SqlString.escapeId(value, false);
|
535
|
+
}
|
536
|
+
|
537
|
+
raw(sql) {
|
538
|
+
return SqlString.raw(sql);
|
539
|
+
}
|
540
|
+
|
541
|
+
_resolveNamedPlaceholders(options) {
|
542
|
+
let unnamed;
|
543
|
+
if (this.config.namedPlaceholders || options.namedPlaceholders) {
|
544
|
+
if (Array.isArray(options.values)) {
|
545
|
+
// if an array is provided as the values, assume the conversion is not necessary.
|
546
|
+
// this allows the usage of unnamed placeholders even if the namedPlaceholders flag is enabled.
|
547
|
+
return;
|
548
|
+
}
|
549
|
+
if (convertNamedPlaceholders === null) {
|
550
|
+
convertNamedPlaceholders = require('named-placeholders')();
|
551
|
+
}
|
552
|
+
unnamed = convertNamedPlaceholders(options.sql, options.values);
|
553
|
+
options.sql = unnamed[0];
|
554
|
+
options.values = unnamed[1];
|
555
|
+
}
|
556
|
+
}
|
557
|
+
|
558
|
+
query(sql, values, cb) {
|
559
|
+
let cmdQuery;
|
560
|
+
if (sql.constructor === Commands.Query) {
|
561
|
+
cmdQuery = sql;
|
562
|
+
} else {
|
563
|
+
cmdQuery = BaseConnection.createQuery(sql, values, cb, this.config);
|
564
|
+
}
|
565
|
+
this._resolveNamedPlaceholders(cmdQuery);
|
566
|
+
const rawSql = this.format(
|
567
|
+
cmdQuery.sql,
|
568
|
+
cmdQuery.values !== undefined ? cmdQuery.values : []
|
569
|
+
);
|
570
|
+
cmdQuery.sql = rawSql;
|
571
|
+
return this.addCommand(cmdQuery);
|
572
|
+
}
|
573
|
+
|
574
|
+
pause() {
|
575
|
+
this._paused = true;
|
576
|
+
this.stream.pause();
|
577
|
+
}
|
578
|
+
|
579
|
+
resume() {
|
580
|
+
let packet;
|
581
|
+
this._paused = false;
|
582
|
+
while ((packet = this._paused_packets.shift())) {
|
583
|
+
this.handlePacket(packet);
|
584
|
+
// don't resume if packet handler paused connection
|
585
|
+
if (this._paused) {
|
586
|
+
return;
|
587
|
+
}
|
588
|
+
}
|
589
|
+
this.stream.resume();
|
590
|
+
}
|
591
|
+
|
592
|
+
// TODO: named placeholders support
|
593
|
+
prepare(options, cb) {
|
594
|
+
if (typeof options === 'string') {
|
595
|
+
options = { sql: options };
|
596
|
+
}
|
597
|
+
return this.addCommand(new Commands.Prepare(options, cb));
|
598
|
+
}
|
599
|
+
|
600
|
+
unprepare(sql) {
|
601
|
+
let options = {};
|
602
|
+
if (typeof sql === 'object') {
|
603
|
+
options = sql;
|
604
|
+
} else {
|
605
|
+
options.sql = sql;
|
606
|
+
}
|
607
|
+
const key = BaseConnection.statementKey(options);
|
608
|
+
const stmt = this._statements.get(key);
|
609
|
+
if (stmt) {
|
610
|
+
this._statements.delete(key);
|
611
|
+
stmt.close();
|
612
|
+
}
|
613
|
+
return stmt;
|
614
|
+
}
|
615
|
+
|
616
|
+
execute(sql, values, cb) {
|
617
|
+
let options = {
|
618
|
+
infileStreamFactory: this.config.infileStreamFactory,
|
619
|
+
};
|
620
|
+
if (typeof sql === 'object') {
|
621
|
+
// execute(options, cb)
|
622
|
+
options = {
|
623
|
+
...options,
|
624
|
+
...sql,
|
625
|
+
sql: sql.sql,
|
626
|
+
values: sql.values,
|
627
|
+
};
|
628
|
+
if (typeof values === 'function') {
|
629
|
+
cb = values;
|
630
|
+
} else {
|
631
|
+
options.values = options.values || values;
|
632
|
+
}
|
633
|
+
} else if (typeof values === 'function') {
|
634
|
+
// execute(sql, cb)
|
635
|
+
cb = values;
|
636
|
+
options.sql = sql;
|
637
|
+
options.values = undefined;
|
638
|
+
} else {
|
639
|
+
// execute(sql, values, cb)
|
640
|
+
options.sql = sql;
|
641
|
+
options.values = values;
|
642
|
+
}
|
643
|
+
this._resolveNamedPlaceholders(options);
|
644
|
+
// check for values containing undefined
|
645
|
+
if (options.values) {
|
646
|
+
//If namedPlaceholder is not enabled and object is passed as bind parameters
|
647
|
+
if (!Array.isArray(options.values)) {
|
648
|
+
throw new TypeError(
|
649
|
+
'Bind parameters must be array if namedPlaceholders parameter is not enabled'
|
650
|
+
);
|
651
|
+
}
|
652
|
+
options.values.forEach((val) => {
|
653
|
+
//If namedPlaceholder is not enabled and object is passed as bind parameters
|
654
|
+
if (!Array.isArray(options.values)) {
|
655
|
+
throw new TypeError(
|
656
|
+
'Bind parameters must be array if namedPlaceholders parameter is not enabled'
|
657
|
+
);
|
658
|
+
}
|
659
|
+
if (val === undefined) {
|
660
|
+
throw new TypeError(
|
661
|
+
'Bind parameters must not contain undefined. To pass SQL NULL specify JS null'
|
662
|
+
);
|
663
|
+
}
|
664
|
+
if (typeof val === 'function') {
|
665
|
+
throw new TypeError(
|
666
|
+
'Bind parameters must not contain function(s). To pass the body of a function as a string call .toString() first'
|
667
|
+
);
|
668
|
+
}
|
669
|
+
});
|
670
|
+
}
|
671
|
+
const executeCommand = new Commands.Execute(options, cb);
|
672
|
+
const prepareCommand = new Commands.Prepare(options, (err, stmt) => {
|
673
|
+
if (err) {
|
674
|
+
// skip execute command if prepare failed, we have main
|
675
|
+
// combined callback here
|
676
|
+
executeCommand.start = function () {
|
677
|
+
return null;
|
678
|
+
};
|
679
|
+
if (cb) {
|
680
|
+
cb(err);
|
681
|
+
} else {
|
682
|
+
executeCommand.emit('error', err);
|
683
|
+
}
|
684
|
+
executeCommand.emit('end');
|
685
|
+
return;
|
686
|
+
}
|
687
|
+
executeCommand.statement = stmt;
|
688
|
+
});
|
689
|
+
this.addCommand(prepareCommand);
|
690
|
+
this.addCommand(executeCommand);
|
691
|
+
return executeCommand;
|
692
|
+
}
|
693
|
+
|
694
|
+
changeUser(options, callback) {
|
695
|
+
if (!callback && typeof options === 'function') {
|
696
|
+
callback = options;
|
697
|
+
options = {};
|
698
|
+
}
|
699
|
+
const charsetNumber = options.charset
|
700
|
+
? ConnectionConfig.getCharsetNumber(options.charset)
|
701
|
+
: this.config.charsetNumber;
|
702
|
+
return this.addCommand(
|
703
|
+
new Commands.ChangeUser(
|
704
|
+
{
|
705
|
+
user: options.user || this.config.user,
|
706
|
+
// for the purpose of multi-factor authentication, or not, the main
|
707
|
+
// password (used for the 1st authentication factor) can also be
|
708
|
+
// provided via the "password1" option
|
709
|
+
password:
|
710
|
+
options.password ||
|
711
|
+
options.password1 ||
|
712
|
+
this.config.password ||
|
713
|
+
this.config.password1,
|
714
|
+
password2: options.password2 || this.config.password2,
|
715
|
+
password3: options.password3 || this.config.password3,
|
716
|
+
passwordSha1: options.passwordSha1 || this.config.passwordSha1,
|
717
|
+
database: options.database || this.config.database,
|
718
|
+
timeout: options.timeout,
|
719
|
+
charsetNumber: charsetNumber,
|
720
|
+
currentConfig: this.config,
|
721
|
+
},
|
722
|
+
(err) => {
|
723
|
+
if (err) {
|
724
|
+
err.fatal = true;
|
725
|
+
}
|
726
|
+
if (callback) {
|
727
|
+
callback(err);
|
728
|
+
}
|
729
|
+
}
|
730
|
+
)
|
731
|
+
);
|
732
|
+
}
|
733
|
+
|
734
|
+
// transaction helpers
|
735
|
+
beginTransaction(cb) {
|
736
|
+
return this.query('START TRANSACTION', cb);
|
737
|
+
}
|
738
|
+
|
739
|
+
commit(cb) {
|
740
|
+
return this.query('COMMIT', cb);
|
741
|
+
}
|
742
|
+
|
743
|
+
rollback(cb) {
|
744
|
+
return this.query('ROLLBACK', cb);
|
745
|
+
}
|
746
|
+
|
747
|
+
ping(cb) {
|
748
|
+
return this.addCommand(new Commands.Ping(cb));
|
749
|
+
}
|
750
|
+
|
751
|
+
_registerSlave(opts, cb) {
|
752
|
+
return this.addCommand(new Commands.RegisterSlave(opts, cb));
|
753
|
+
}
|
754
|
+
|
755
|
+
_binlogDump(opts, cb) {
|
756
|
+
return this.addCommand(new Commands.BinlogDump(opts, cb));
|
757
|
+
}
|
758
|
+
|
759
|
+
// currently just alias to close
|
760
|
+
destroy() {
|
761
|
+
this.close();
|
762
|
+
}
|
763
|
+
|
764
|
+
close() {
|
765
|
+
if (this.connectTimeout) {
|
766
|
+
Timers.clearTimeout(this.connectTimeout);
|
767
|
+
this.connectTimeout = null;
|
768
|
+
}
|
769
|
+
this._closing = true;
|
770
|
+
this.stream.end();
|
771
|
+
this.addCommand = this._addCommandClosedState;
|
772
|
+
}
|
773
|
+
|
774
|
+
createBinlogStream(opts) {
|
775
|
+
// TODO: create proper stream class
|
776
|
+
// TODO: use through2
|
777
|
+
let test = 1;
|
778
|
+
const stream = new Readable({ objectMode: true });
|
779
|
+
stream._read = function () {
|
780
|
+
return {
|
781
|
+
data: test++,
|
782
|
+
};
|
783
|
+
};
|
784
|
+
this._registerSlave(opts, () => {
|
785
|
+
const dumpCmd = this._binlogDump(opts);
|
786
|
+
dumpCmd.on('event', (ev) => {
|
787
|
+
stream.push(ev);
|
788
|
+
});
|
789
|
+
dumpCmd.on('eof', () => {
|
790
|
+
stream.push(null);
|
791
|
+
// if non-blocking, then close stream to prevent errors
|
792
|
+
if (opts.flags && opts.flags & 0x01) {
|
793
|
+
this.close();
|
794
|
+
}
|
795
|
+
});
|
796
|
+
// TODO: pipe errors as well
|
797
|
+
});
|
798
|
+
return stream;
|
799
|
+
}
|
800
|
+
|
801
|
+
connect(cb) {
|
802
|
+
if (!cb) {
|
803
|
+
return;
|
804
|
+
}
|
805
|
+
if (this._fatalError || this._protocolError) {
|
806
|
+
return cb(this._fatalError || this._protocolError);
|
807
|
+
}
|
808
|
+
if (this._handshakePacket) {
|
809
|
+
return cb(null, this);
|
810
|
+
}
|
811
|
+
let connectCalled = 0;
|
812
|
+
function callbackOnce(isErrorHandler) {
|
813
|
+
return function (param) {
|
814
|
+
if (!connectCalled) {
|
815
|
+
if (isErrorHandler) {
|
816
|
+
cb(param);
|
817
|
+
} else {
|
818
|
+
cb(null, param);
|
819
|
+
}
|
820
|
+
}
|
821
|
+
connectCalled = 1;
|
822
|
+
};
|
823
|
+
}
|
824
|
+
this.once('error', callbackOnce(true));
|
825
|
+
this.once('connect', callbackOnce(false));
|
826
|
+
}
|
827
|
+
|
828
|
+
// ===================================
|
829
|
+
// outgoing server connection methods
|
830
|
+
// ===================================
|
831
|
+
writeColumns(columns) {
|
832
|
+
this.writePacket(Packets.ResultSetHeader.toPacket(columns.length));
|
833
|
+
columns.forEach((column) => {
|
834
|
+
this.writePacket(
|
835
|
+
Packets.ColumnDefinition.toPacket(column, this.serverConfig.encoding)
|
836
|
+
);
|
837
|
+
});
|
838
|
+
this.writeEof();
|
839
|
+
}
|
840
|
+
|
841
|
+
// row is array of columns, not hash
|
842
|
+
writeTextRow(column) {
|
843
|
+
this.writePacket(
|
844
|
+
Packets.TextRow.toPacket(column, this.serverConfig.encoding)
|
845
|
+
);
|
846
|
+
}
|
847
|
+
|
848
|
+
writeBinaryRow(column) {
|
849
|
+
this.writePacket(
|
850
|
+
Packets.BinaryRow.toPacket(column, this.serverConfig.encoding)
|
851
|
+
);
|
852
|
+
}
|
853
|
+
|
854
|
+
writeTextResult(rows, columns, binary = false) {
|
855
|
+
this.writeColumns(columns);
|
856
|
+
rows.forEach((row) => {
|
857
|
+
const arrayRow = new Array(columns.length);
|
858
|
+
columns.forEach((column) => {
|
859
|
+
arrayRow.push(row[column.name]);
|
860
|
+
});
|
861
|
+
if (binary) {
|
862
|
+
this.writeBinaryRow(arrayRow);
|
863
|
+
} else this.writeTextRow(arrayRow);
|
864
|
+
});
|
865
|
+
this.writeEof();
|
866
|
+
}
|
867
|
+
|
868
|
+
writeEof(warnings, statusFlags) {
|
869
|
+
this.writePacket(Packets.EOF.toPacket(warnings, statusFlags));
|
870
|
+
}
|
871
|
+
|
872
|
+
writeOk(args) {
|
873
|
+
if (!args) {
|
874
|
+
args = { affectedRows: 0 };
|
875
|
+
}
|
876
|
+
this.writePacket(Packets.OK.toPacket(args, this.serverConfig.encoding));
|
877
|
+
}
|
878
|
+
|
879
|
+
writeError(args) {
|
880
|
+
// if we want to send error before initial hello was sent, use default encoding
|
881
|
+
const encoding = this.serverConfig ? this.serverConfig.encoding : 'cesu8';
|
882
|
+
this.writePacket(Packets.Error.toPacket(args, encoding));
|
883
|
+
}
|
884
|
+
|
885
|
+
serverHandshake(args) {
|
886
|
+
this.serverConfig = args;
|
887
|
+
this.serverConfig.encoding =
|
888
|
+
CharsetToEncoding[this.serverConfig.characterSet];
|
889
|
+
return this.addCommand(new Commands.ServerHandshake(args));
|
890
|
+
}
|
891
|
+
|
892
|
+
// ===============================================================
|
893
|
+
end(callback) {
|
894
|
+
if (this.config.isServer) {
|
895
|
+
this._closing = true;
|
896
|
+
const quitCmd = new EventEmitter();
|
897
|
+
setImmediate(() => {
|
898
|
+
this.stream.end();
|
899
|
+
quitCmd.emit('end');
|
900
|
+
});
|
901
|
+
return quitCmd;
|
902
|
+
}
|
903
|
+
// trigger error if more commands enqueued after end command
|
904
|
+
const quitCmd = this.addCommand(new Commands.Quit(callback));
|
905
|
+
this.addCommand = this._addCommandClosedState;
|
906
|
+
return quitCmd;
|
907
|
+
}
|
908
|
+
|
909
|
+
static createQuery(sql, values, cb, config) {
|
910
|
+
let options = {
|
911
|
+
rowsAsArray: config.rowsAsArray,
|
912
|
+
infileStreamFactory: config.infileStreamFactory,
|
913
|
+
};
|
914
|
+
if (typeof sql === 'object') {
|
915
|
+
// query(options, cb)
|
916
|
+
options = {
|
917
|
+
...options,
|
918
|
+
...sql,
|
919
|
+
sql: sql.sql,
|
920
|
+
values: sql.values,
|
921
|
+
};
|
922
|
+
if (typeof values === 'function') {
|
923
|
+
cb = values;
|
924
|
+
} else if (values !== undefined) {
|
925
|
+
options.values = values;
|
926
|
+
}
|
927
|
+
} else if (typeof values === 'function') {
|
928
|
+
// query(sql, cb)
|
929
|
+
cb = values;
|
930
|
+
options.sql = sql;
|
931
|
+
options.values = undefined;
|
932
|
+
} else {
|
933
|
+
// query(sql, values, cb)
|
934
|
+
options.sql = sql;
|
935
|
+
options.values = values;
|
936
|
+
}
|
937
|
+
return new Commands.Query(options, cb);
|
938
|
+
}
|
939
|
+
|
940
|
+
static statementKey(options) {
|
941
|
+
return `${typeof options.nestTables}/${options.nestTables}/${options.rowsAsArray}${options.sql}`;
|
942
|
+
}
|
943
|
+
}
|
944
|
+
|
945
|
+
module.exports = BaseConnection;
|