index.js 4.5 KB

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