index.js 4.3 KB

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