execute.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict';
  2. const Command = require('./command.js');
  3. const Query = require('./query.js');
  4. const Packets = require('../packets/index.js');
  5. const getBinaryParser = require('../parsers/binary_parser.js');
  6. class Execute extends Command {
  7. constructor(options, callback) {
  8. super();
  9. this.statement = options.statement;
  10. this.sql = options.sql;
  11. this.values = options.values;
  12. this.onResult = callback;
  13. this.parameters = options.values;
  14. this.insertId = 0;
  15. this.timeout = options.timeout;
  16. this.queryTimeout = null;
  17. this._rows = [];
  18. this._fields = [];
  19. this._result = [];
  20. this._fieldCount = 0;
  21. this._rowParser = null;
  22. this._executeOptions = options;
  23. this._resultIndex = 0;
  24. this._localStream = null;
  25. this._unpipeStream = function() {};
  26. this._streamFactory = options.infileStreamFactory;
  27. this._connection = null;
  28. }
  29. buildParserFromFields(fields, connection) {
  30. return getBinaryParser(fields, this.options, connection.config);
  31. }
  32. start(packet, connection) {
  33. this._connection = connection;
  34. this.options = Object.assign({}, connection.config, this._executeOptions);
  35. this._setTimeout();
  36. const executePacket = new Packets.Execute(
  37. this.statement.id,
  38. this.parameters,
  39. connection.config.charsetNumber,
  40. connection.config.timezone
  41. );
  42. //For reasons why this try-catch is here, please see
  43. // https://github.com/sidorares/node-mysql2/pull/689
  44. //For additional discussion, see
  45. // 1. https://github.com/sidorares/node-mysql2/issues/493
  46. // 2. https://github.com/sidorares/node-mysql2/issues/187
  47. // 3. https://github.com/sidorares/node-mysql2/issues/480
  48. try {
  49. connection.writePacket(executePacket.toPacket(1));
  50. } catch (error) {
  51. this.onResult(error);
  52. }
  53. return Execute.prototype.resultsetHeader;
  54. }
  55. readField(packet, connection) {
  56. let fields;
  57. // disabling for now, but would be great to find reliable way to parse fields only once
  58. // fields reported by prepare can be empty at all or just incorrect - see #169
  59. //
  60. // perfomance optimisation: if we already have this field parsed in statement header, use one from header
  61. // const field = this.statement.columns.length == this._fieldCount ?
  62. // this.statement.columns[this._receivedFieldsCount] : new Packets.ColumnDefinition(packet);
  63. const field = new Packets.ColumnDefinition(
  64. packet,
  65. connection.clientEncoding
  66. );
  67. this._receivedFieldsCount++;
  68. this._fields[this._resultIndex].push(field);
  69. if (this._receivedFieldsCount === this._fieldCount) {
  70. fields = this._fields[this._resultIndex];
  71. this.emit('fields', fields, this._resultIndex);
  72. return Execute.prototype.fieldsEOF;
  73. }
  74. return Execute.prototype.readField;
  75. }
  76. fieldsEOF(packet, connection) {
  77. // check EOF
  78. if (!packet.isEOF()) {
  79. return connection.protocolError('Expected EOF packet');
  80. }
  81. this._rowParser = new (this.buildParserFromFields(
  82. this._fields[this._resultIndex],
  83. connection
  84. ))();
  85. return Execute.prototype.row;
  86. }
  87. }
  88. Execute.prototype.done = Query.prototype.done;
  89. Execute.prototype.doneInsert = Query.prototype.doneInsert;
  90. Execute.prototype.resultsetHeader = Query.prototype.resultsetHeader;
  91. Execute.prototype._findOrCreateReadStream =
  92. Query.prototype._findOrCreateReadStream;
  93. Execute.prototype._streamLocalInfile = Query.prototype._streamLocalInfile;
  94. Execute.prototype._setTimeout = Query.prototype._setTimeout;
  95. Execute.prototype._handleTimeoutError = Query.prototype._handleTimeoutError;
  96. Execute.prototype.row = Query.prototype.row;
  97. Execute.prototype.stream = Query.prototype.stream;
  98. module.exports = Execute;