index.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. // This file was modified by Oracle on September 21, 2021.
  6. // The new AuthNextFactor packet is now available.
  7. // Modifications copyright (c) 2021, Oracle and/or its affiliates.
  8. 'use strict';
  9. const process = require('process');
  10. const AuthNextFactor = require('./auth_next_factor');
  11. const AuthSwitchRequest = require('./auth_switch_request');
  12. const AuthSwitchRequestMoreData = require('./auth_switch_request_more_data');
  13. const AuthSwitchResponse = require('./auth_switch_response');
  14. const BinaryRow = require('./binary_row');
  15. const BinlogDump = require('./binlog_dump');
  16. const ChangeUser = require('./change_user');
  17. const CloseStatement = require('./close_statement');
  18. const ColumnDefinition = require('./column_definition');
  19. const Execute = require('./execute');
  20. const Handshake = require('./handshake');
  21. const HandshakeResponse = require('./handshake_response');
  22. const PrepareStatement = require('./prepare_statement');
  23. const PreparedStatementHeader = require('./prepared_statement_header');
  24. const Query = require('./query');
  25. const RegisterSlave = require('./register_slave');
  26. const ResetConnection = require('./reset_connection');
  27. const ResultSetHeader = require('./resultset_header');
  28. const SSLRequest = require('./ssl_request');
  29. const TextRow = require('./text_row');
  30. const ctorMap = {
  31. AuthNextFactor,
  32. AuthSwitchRequest,
  33. AuthSwitchRequestMoreData,
  34. AuthSwitchResponse,
  35. BinaryRow,
  36. BinlogDump,
  37. ChangeUser,
  38. CloseStatement,
  39. ColumnDefinition,
  40. Execute,
  41. Handshake,
  42. HandshakeResponse,
  43. PrepareStatement,
  44. PreparedStatementHeader,
  45. Query,
  46. RegisterSlave,
  47. ResetConnection,
  48. ResultSetHeader,
  49. SSLRequest,
  50. TextRow,
  51. };
  52. Object.entries(ctorMap).forEach(([name, ctor]) => {
  53. module.exports[name] = ctor;
  54. // monkey-patch it to include name if debug is on
  55. if (process.env.NODE_DEBUG) {
  56. if (ctor.prototype.toPacket) {
  57. const old = ctor.prototype.toPacket;
  58. ctor.prototype.toPacket = function () {
  59. const p = old.call(this);
  60. p._name = name;
  61. return p;
  62. };
  63. }
  64. }
  65. });
  66. // simple packets:
  67. const Packet = require('./packet');
  68. exports.Packet = Packet;
  69. class OK {
  70. static toPacket(args, encoding) {
  71. args = args || {};
  72. const affectedRows = args.affectedRows || 0;
  73. const insertId = args.insertId || 0;
  74. const serverStatus = args.serverStatus || 0;
  75. const warningCount = args.warningCount || 0;
  76. const message = args.message || '';
  77. let length = 9 + Packet.lengthCodedNumberLength(affectedRows);
  78. length += Packet.lengthCodedNumberLength(insertId);
  79. const buffer = Buffer.allocUnsafe(length);
  80. const packet = new Packet(0, buffer, 0, length);
  81. packet.offset = 4;
  82. packet.writeInt8(0);
  83. packet.writeLengthCodedNumber(affectedRows);
  84. packet.writeLengthCodedNumber(insertId);
  85. packet.writeInt16(serverStatus);
  86. packet.writeInt16(warningCount);
  87. packet.writeString(message, encoding);
  88. packet._name = 'OK';
  89. return packet;
  90. }
  91. }
  92. exports.OK = OK;
  93. // warnings, statusFlags
  94. class EOF {
  95. static toPacket(warnings, statusFlags) {
  96. if (typeof warnings === 'undefined') {
  97. warnings = 0;
  98. }
  99. if (typeof statusFlags === 'undefined') {
  100. statusFlags = 0;
  101. }
  102. const packet = new Packet(0, Buffer.allocUnsafe(9), 0, 9);
  103. packet.offset = 4;
  104. packet.writeInt8(0xfe);
  105. packet.writeInt16(warnings);
  106. packet.writeInt16(statusFlags);
  107. packet._name = 'EOF';
  108. return packet;
  109. }
  110. }
  111. exports.EOF = EOF;
  112. class Error {
  113. static toPacket(args, encoding) {
  114. const length = 13 + Buffer.byteLength(args.message, 'utf8');
  115. const packet = new Packet(0, Buffer.allocUnsafe(length), 0, length);
  116. packet.offset = 4;
  117. packet.writeInt8(0xff);
  118. packet.writeInt16(args.code);
  119. // TODO: sql state parameter
  120. packet.writeString('#_____', encoding);
  121. packet.writeString(args.message, encoding);
  122. packet._name = 'Error';
  123. return packet;
  124. }
  125. static fromPacket(packet) {
  126. packet.readInt8(); // marker
  127. const code = packet.readInt16();
  128. packet.readString(1, 'ascii'); // sql state marker
  129. // The SQL state of the ERR_Packet which is always 5 bytes long.
  130. // https://dev.mysql.com/doc/dev/mysql-server/8.0.11/page_protocol_basic_dt_strings.html#sect_protocol_basic_dt_string_fix
  131. packet.readString(5, 'ascii'); // sql state (ignore for now)
  132. const message = packet.readNullTerminatedString('utf8');
  133. const error = new Error();
  134. error.message = message;
  135. error.code = code;
  136. return error;
  137. }
  138. }
  139. exports.Error = Error;