'use strict'; const Command = require('./command.js'); const Query = require('./query.js'); const Packets = require('../packets/index.js'); const getBinaryParser = require('../parsers/binary_parser.js'); class Execute extends Command { constructor(options, callback) { super(); this.statement = options.statement; this.sql = options.sql; this.values = options.values; this.onResult = callback; this.parameters = options.values; this.insertId = 0; this.timeout = options.timeout; this.queryTimeout = null; this._rows = []; this._fields = []; this._result = []; this._fieldCount = 0; this._rowParser = null; this._executeOptions = options; this._resultIndex = 0; this._localStream = null; this._unpipeStream = function() {}; this._streamFactory = options.infileStreamFactory; this._connection = null; } buildParserFromFields(fields, connection) { return getBinaryParser(fields, this.options, connection.config); } start(packet, connection) { this._connection = connection; this.options = Object.assign({}, connection.config, this._executeOptions); this._setTimeout(); const executePacket = new Packets.Execute( this.statement.id, this.parameters, connection.config.charsetNumber, connection.config.timezone ); //For reasons why this try-catch is here, please see // https://github.com/sidorares/node-mysql2/pull/689 //For additional discussion, see // 1. https://github.com/sidorares/node-mysql2/issues/493 // 2. https://github.com/sidorares/node-mysql2/issues/187 // 3. https://github.com/sidorares/node-mysql2/issues/480 try { connection.writePacket(executePacket.toPacket(1)); } catch (error) { this.onResult(error); } return Execute.prototype.resultsetHeader; } readField(packet, connection) { let fields; // disabling for now, but would be great to find reliable way to parse fields only once // fields reported by prepare can be empty at all or just incorrect - see #169 // // perfomance optimisation: if we already have this field parsed in statement header, use one from header // const field = this.statement.columns.length == this._fieldCount ? // this.statement.columns[this._receivedFieldsCount] : new Packets.ColumnDefinition(packet); const field = new Packets.ColumnDefinition( packet, connection.clientEncoding ); this._receivedFieldsCount++; this._fields[this._resultIndex].push(field); if (this._receivedFieldsCount === this._fieldCount) { fields = this._fields[this._resultIndex]; this.emit('fields', fields, this._resultIndex); return Execute.prototype.fieldsEOF; } return Execute.prototype.readField; } fieldsEOF(packet, connection) { // check EOF if (!packet.isEOF()) { return connection.protocolError('Expected EOF packet'); } this._rowParser = new (this.buildParserFromFields( this._fields[this._resultIndex], connection ))(); return Execute.prototype.row; } } Execute.prototype.done = Query.prototype.done; Execute.prototype.doneInsert = Query.prototype.doneInsert; Execute.prototype.resultsetHeader = Query.prototype.resultsetHeader; Execute.prototype._findOrCreateReadStream = Query.prototype._findOrCreateReadStream; Execute.prototype._streamLocalInfile = Query.prototype._streamLocalInfile; Execute.prototype._setTimeout = Query.prototype._setTimeout; Execute.prototype._handleTimeoutError = Query.prototype._handleTimeoutError; Execute.prototype.row = Query.prototype.row; Execute.prototype.stream = Query.prototype.stream; module.exports = Execute;