DiscofyAPI/node_modules/mariadb/lib/cmd/command.js

166 lines
4.5 KiB
JavaScript

'use strict';
const EventEmitter = require('events');
const Errors = require('../misc/errors');
const ServerStatus = require('../const/server-status');
const StateChange = require('../const/state-change');
const Collations = require('../const/collations');
const OkPacket = require('./class/ok-packet');
/**
* Default command interface.
*/
class Command extends EventEmitter {
constructor(resolve, reject) {
super();
this.sequenceNo = -1;
this.compressSequenceNo = -1;
this.resolve = resolve;
this.reject = reject;
this.sending = false;
}
displaySql() {}
/**
* Throw an an unexpected error.
* server exchange will still be read to keep connection in a good state, but promise will be rejected.
*
* @param msg message
* @param fatal is error fatal for connection
* @param info current server state information
* @param sqlState error sqlState
* @param errno error number
*/
throwUnexpectedError(msg, fatal, info, sqlState, errno) {
if (this.reject) {
process.nextTick(
this.reject,
Errors.createError(msg, fatal, info, sqlState, errno, this.stack, false)
);
this.resolve = null;
this.reject = null;
}
}
/**
* Create and throw new Error from error information
* only first called throwing an error or successfully end will be executed.
*
* @param msg message
* @param fatal is error fatal for connection
* @param info current server state information
* @param sqlState error sqlState
* @param errno error number
*/
throwNewError(msg, fatal, info, sqlState, errno) {
this.onPacketReceive = null;
if (this.reject) {
process.nextTick(
this.reject,
Errors.createError(msg, fatal, info, sqlState, errno, this.stack, false)
);
this.resolve = null;
this.reject = null;
}
this.emit('end');
}
/**
* Throw Error
* only first called throwing an error or successfully end will be executed.
*
* @param err error to be thrown
* @param info current server state information
*/
throwError(err, info) {
this.onPacketReceive = null;
if (this.reject) {
if (this.stack) {
err = Errors.createError(
err.message,
err.fatal,
info,
err.sqlState,
err.errno,
this.stack,
false
);
}
this.resolve = null;
process.nextTick(this.reject, err);
this.reject = null;
}
this.emit('end', err);
}
/**
* Successfully end command.
* only first called throwing an error or successfully end will be executed.
*
* @param val return value.
*/
successEnd(val) {
this.onPacketReceive = null;
if (this.resolve) {
this.reject = null;
process.nextTick(this.resolve, val);
this.resolve = null;
}
this.emit('end');
}
static parseOkPacket(packet, out, opts, info) {
packet.skip(1); //skip header
const affectedRows = packet.readUnsignedLength();
const insertId = opts.supportBigInt
? packet.readSignedLengthBigInt()
: packet.readSignedLength();
info.status = packet.readUInt16();
const okPacket = new OkPacket(affectedRows, insertId, packet.readUInt16());
if (info.status & ServerStatus.SESSION_STATE_CHANGED) {
packet.skipLengthCodedNumber();
while (packet.remaining()) {
const subPacket = packet.subPacketLengthEncoded();
while (subPacket.remaining()) {
const type = subPacket.readUInt8();
switch (type) {
case StateChange.SESSION_TRACK_SYSTEM_VARIABLES:
const subSubPacket = subPacket.subPacketLengthEncoded();
const variable = subSubPacket.readStringLength();
const value = subSubPacket.readStringLength();
switch (variable) {
case 'character_set_client':
opts.collation = Collations.fromCharset(value);
if (opts.collation === undefined) {
this.throwError(new Error("unknown charset : '" + value + "'"), info);
return;
}
opts.emit('collation', opts.collation);
break;
default:
//variable not used by driver
}
break;
case StateChange.SESSION_TRACK_SCHEMA:
const subSubPacket2 = subPacket.subPacketLengthEncoded();
info.database = subSubPacket2.readStringLength();
break;
}
}
}
}
return okPacket;
}
}
module.exports = Command;