API inicial

This commit is contained in:
2021-03-25 17:23:36 +01:00
commit 218326c402
1878 changed files with 274122 additions and 0 deletions

276
node_modules/mariadb/lib/cmd/batch-bulk.js generated vendored Normal file
View File

@@ -0,0 +1,276 @@
'use strict';
const CommonBinary = require('./common-binary-cmd');
const Errors = require('../misc/errors');
const Parse = require('../misc/parse');
const BulkPacket = require('../io/bulk-packet');
/**
* Protocol COM_STMT_BULK_EXECUTE
* see : https://mariadb.com/kb/en/library/com_stmt_bulk_execute/
*/
class BatchBulk extends CommonBinary {
constructor(resolve, reject, options, connOpts, sql, values) {
super(resolve, reject, options, connOpts, sql, values);
this.onPacketReceive = this.readPrepareResultPacket;
}
/**
* Send COM_STMT_BULK_EXECUTE
*
* @param out output writer
* @param opts connection options
* @param info connection information
*/
start(out, opts, info) {
this.sending = true;
this.info = info;
this.values = this.initialValues;
if (this.opts.timeout) {
const err = Errors.createError(
'Cannot use timeout for Batch statement',
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return;
}
let questionMarkSql = this.sql;
if (this.opts.namedPlaceholders) {
const res = Parse.searchPlaceholder(
this.sql,
info,
this.initialValues,
this.displaySql.bind(this)
);
questionMarkSql = res.sql;
this.values = res.values;
}
if (!this.validateParameters(info)) {
this.sending = false;
return;
}
//send COM_STMT_PREPARE command
this.out = out;
this.packet = new BulkPacket(this.opts, out, this.values[0]);
out.startPacket(this);
out.writeInt8(0x16);
out.writeString(questionMarkSql);
out.flushBuffer(true);
if (this.opts.pipelining) {
out.startPacket(this);
this.valueIdx = 0;
this.sendQueries();
} else {
this.out = out;
}
}
sendQueries() {
let flushed = false;
while (!flushed && this.sending && this.valueIdx < this.values.length) {
this.valueRow = this.values[this.valueIdx++];
//********************************************
// send params
//********************************************
const len = this.valueRow.length;
for (let i = 0; i < len; i++) {
const value = this.valueRow[i];
if (value === null) {
flushed = this.packet.writeInt8(0x01) || flushed;
continue;
}
//********************************************
// param has no stream. directly write in buffer
//********************************************
flushed = this.writeParam(this.packet, value, this.opts, this.info) || flushed;
}
const last = this.valueIdx === this.values.length;
flushed = this.packet.mark(last, last ? null : this.values[this.valueIdx]) || flushed;
}
if (this.valueIdx < this.values.length && !this.packet.haveErrorResponse) {
//there is still data to send
setImmediate(this.sendQueries.bind(this));
} else {
if (this.sending && this.valueIdx === this.values.length) this.emit('send_end');
this.sending = false;
}
}
displaySql() {
if (this.opts && this.initialValues) {
if (this.sql.length > this.opts.debugLen) {
return 'sql: ' + this.sql.substring(0, this.opts.debugLen) + '...';
}
let sqlMsg = 'sql: ' + this.sql + ' - parameters:';
sqlMsg += '[';
for (let i = 0; i < this.initialValues.length; i++) {
if (i !== 0) sqlMsg += ',';
let param = this.initialValues[i];
sqlMsg = this.logParameters(sqlMsg, param);
if (sqlMsg.length > this.opts.debugLen) {
sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
break;
}
}
sqlMsg += ']';
return sqlMsg;
}
return 'sql: ' + this.sql + ' - parameters:[]';
}
success(val) {
this.packet.waitingResponseNo--;
if (!this.opts.pipelining && this.packet.statementId === -1) {
this.packet.statementId = this.statementId;
this.out.startPacket(this);
this.valueIdx = 0;
this.sendQueries();
this._responseIndex++;
this.onPacketReceive = this.readResponsePacket;
return;
}
if (!this.sending && this.packet.waitingResponseNo === 0) {
//send COM_STMT_CLOSE packet
if (!this.firstError || !this.firstError.fatal) {
this.sequenceNo = -1;
this.compressSequenceNo = -1;
this.out.startPacket(this);
this.out.writeInt8(0x19);
this.out.writeInt32(this.statementId);
this.out.flushBuffer(true);
}
this.sending = false;
this.emit('send_end');
if (this.packet.haveErrorResponse) {
this.packet = null;
this.resolve = null;
this.onPacketReceive = null;
this._columns = null;
this._rows = null;
process.nextTick(this.reject, this.firstError);
this.reject = null;
this.emit('end', this.firstError);
} else {
this.packet = null;
let totalAffectedRows = 0;
this._rows.forEach((row) => {
totalAffectedRows += row.affectedRows;
});
const rs = {
affectedRows: totalAffectedRows,
insertId: this._rows[0].insertId,
warningStatus: this._rows[this._rows.length - 1].warningStatus
};
this.successEnd(rs);
this._columns = null;
this._rows = null;
}
return;
}
if (!this.packet.haveErrorResponse) {
this._responseIndex++;
this.onPacketReceive = this.readResponsePacket;
}
}
throwError(err, info) {
this.packet.waitingResponseNo--;
this.sending = false;
if (this.packet && !this.packet.haveErrorResponse) {
if (err.fatal) {
this.packet.waitingResponseNo = 0;
}
if (this.stack) {
err = Errors.createError(
err.message,
err.fatal,
info,
err.sqlState,
err.errno,
this.stack,
false
);
}
this.firstError = err;
this.packet.endedWithError();
}
if (!this.sending && this.packet.waitingResponseNo === 0) {
this.resolve = null;
//send COM_STMT_CLOSE packet
if (!err.fatal && this.statementId) {
this.sequenceNo = -1;
this.compressSequenceNo = -1;
this.out.startPacket(this);
this.out.writeInt8(0x19);
this.out.writeInt32(this.statementId);
this.out.flushBuffer(true);
}
this.emit('send_end');
process.nextTick(this.reject, this.firstError);
this.reject = null;
this.onPacketReceive = null;
this.emit('end', this.firstError);
} else {
this._responseIndex++;
this.onPacketReceive = this.readResponsePacket;
}
}
/**
* Validate that parameters exists and are defined.
*
* @param info connection info
* @returns {boolean} return false if any error occur.
*/
validateParameters(info) {
//validate parameter size.
for (let r = 0; r < this.values.length; r++) {
if (!Array.isArray(this.values[r])) this.values[r] = [this.values[r]];
//validate parameter is defined.
for (let i = 0; i < this.values[r].length; i++) {
if (this.values[r][i] === undefined) {
this.emit('send_end');
this.throwNewError(
'Parameter at position ' +
(i + 1) +
' is undefined for values ' +
r +
'\n' +
this.displaySql(),
false,
info,
'HY000',
Errors.ER_PARAMETER_UNDEFINED
);
return false;
}
}
}
return true;
}
}
module.exports = BatchBulk;

370
node_modules/mariadb/lib/cmd/batch-rewrite.js generated vendored Normal file
View File

@@ -0,0 +1,370 @@
'use strict';
const CommonText = require('./common-text-cmd');
const Errors = require('../misc/errors');
const Parse = require('../misc/parse');
const RewritePacket = require('../io/rewrite-packet');
const QUOTE = 0x27;
/**
* Protocol COM_QUERY
* see : https://mariadb.com/kb/en/library/com_query/
*/
class BatchRewrite extends CommonText {
constructor(resolve, reject, options, connOpts, sql, values) {
super(resolve, reject, options, connOpts, sql, values);
}
/**
* Send COM_QUERY
*
* @param out output writer
* @param opts connection options
* @param info connection information
*/
start(out, opts, info) {
this.sending = true;
this.info = info;
if (this.opts.timeout) {
const err = Errors.createError(
'Cannot use timeout for Batch statement',
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return;
}
if (this.initialValues.length === 0) this.initialValues = [[]];
if (this.opts.namedPlaceholders) {
this.parseResults = Parse.splitRewritableNamedParameterQuery(this.sql, this.initialValues);
this.values = this.parseResults.values;
} else {
this.parseResults = Parse.splitRewritableQuery(this.sql);
this.values = this.initialValues;
if (!this.validateParameters(info)) {
this.sending = false;
return;
}
}
out.startPacket(this);
this.packet = new RewritePacket(
this.opts.maxAllowedPacket,
out,
this.parseResults.partList[0],
this.parseResults.partList[this.parseResults.partList.length - 1]
);
this.onPacketReceive = this.readResponsePacket;
this.valueIdx = 0;
this.sendQueries();
}
sendQueries() {
let flushed = false;
while (!flushed && this.sending && this.valueIdx < this.values.length) {
this.valueRow = this.values[this.valueIdx++];
//********************************************
// send params
//********************************************
const len = this.parseResults.partList.length - 3;
for (let i = 0; i < len; i++) {
const value = this.valueRow[i];
flushed = this.packet.writeString(this.parseResults.partList[i + 1]) || flushed;
if (value === null) {
flushed = this.packet.writeStringAscii('NULL') || flushed;
continue;
}
if (
typeof value === 'object' &&
typeof value.pipe === 'function' &&
typeof value.read === 'function'
) {
//********************************************
// param is stream,
// now all params will be written by event
//********************************************
this.registerStreamSendEvent(this.packet, this.info);
this.currentParam = i;
this.packet.writeInt8(QUOTE); //'
value.on(
'data',
function (chunk) {
this.packet.writeBufferEscape(chunk);
}.bind(this)
);
value.on(
'end',
function () {
this.packet.writeInt8(QUOTE); //'
this.currentParam++;
this.paramWritten();
}.bind(this)
);
return;
} else {
//********************************************
// param isn't stream. directly write in buffer
//********************************************
flushed = this.writeParam(this.packet, value, this.opts, this.info) || flushed;
}
}
this.packet.writeString(this.parseResults.partList[this.parseResults.partList.length - 2]);
this.packet.mark(!this.parseResults.reWritable || this.valueIdx === this.values.length);
}
if (this.valueIdx < this.values.length && !this.packet.haveErrorResponse) {
//there is still data to send
setImmediate(this.sendQueries.bind(this));
} else {
if (this.sending && this.valueIdx === this.values.length) this.emit('send_end');
this.sending = false;
}
}
displaySql() {
if (this.opts && this.initialValues) {
if (this.sql.length > this.opts.debugLen) {
return 'sql: ' + this.sql.substring(0, this.opts.debugLen) + '...';
}
let sqlMsg = 'sql: ' + this.sql + ' - parameters:';
sqlMsg += '[';
for (let i = 0; i < this.initialValues.length; i++) {
if (i !== 0) sqlMsg += ',';
let param = this.initialValues[i];
sqlMsg = this.logParameters(sqlMsg, param);
if (sqlMsg.length > this.opts.debugLen) {
sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
break;
}
}
sqlMsg += ']';
return sqlMsg;
}
return 'sql: ' + this.sql + ' - parameters:[]';
}
success(val) {
this.packet.waitingResponseNo--;
if (this.packet.haveErrorResponse) {
if (!this.sending && this.packet.waitingResponseNo === 0) {
this.packet = null;
this.onPacketReceive = null;
this.resolve = null;
this._columns = null;
this._rows = null;
process.nextTick(this.reject, this.firstError);
this.reject = null;
this.emit('end', this.firstError);
}
} else {
if (!this.sending && this.packet.waitingResponseNo === 0) {
if (this.parseResults.reWritable) {
this.packet = null;
let totalAffectedRows = 0;
this._rows.forEach((row) => {
totalAffectedRows += row.affectedRows;
});
const rs = {
affectedRows: totalAffectedRows,
insertId: this._rows[0].insertId,
warningStatus: this._rows[this._rows.length - 1].warningStatus
};
this.successEnd(rs);
return;
} else {
this.successEnd(this._rows);
}
this._columns = null;
this._rows = null;
return;
}
this._responseIndex++;
this.onPacketReceive = this.readResponsePacket;
}
}
throwError(err, info) {
this.packet.waitingResponseNo--;
this.sending = false;
if (this.packet && !this.packet.haveErrorResponse) {
if (err.fatal) {
this.packet.waitingResponseNo = 0;
}
if (this.stack) {
err = Errors.createError(
err.message,
err.fatal,
info,
err.sqlState,
err.errno,
this.stack,
false
);
}
this.firstError = err;
this.packet.endedWithError();
}
if (!this.sending && this.packet.waitingResponseNo === 0) {
this.packet = null;
this.onPacketReceive = null;
this.resolve = null;
process.nextTick(this.reject, this.firstError);
this.reject = null;
this.emit('end', this.firstError);
} else {
this._responseIndex++;
this.onPacketReceive = this.readResponsePacket;
}
}
/**
* Validate that parameters exists and are defined.
*
* @param info connection info
* @returns {boolean} return false if any error occur.
*/
validateParameters(info) {
//validate parameter size.
for (let r = 0; r < this.values.length; r++) {
let val = this.values[r];
if (!Array.isArray(val)) {
val = [val];
this.values[r] = val;
}
if (this.parseResults.partList.length - 3 > val.length) {
this.emit('send_end');
this.throwNewError(
'Parameter at position ' +
val.length +
' is not set for values ' +
r +
'\n' +
this.displaySql(),
false,
info,
'HY000',
Errors.ER_MISSING_PARAMETER
);
return false;
}
//validate parameter is defined.
for (let i = 0; i < this.parseResults.partList.length - 3; i++) {
if (val[i] === undefined) {
this.emit('send_end');
this.throwNewError(
'Parameter at position ' +
(i + 1) +
' is undefined for values ' +
r +
'\n' +
this.displaySql(),
false,
info,
'HY000',
Errors.ER_PARAMETER_UNDEFINED
);
return false;
}
}
}
return true;
}
/**
* Define params events.
* Each parameter indicate that he is written to socket,
* emitting event so next parameter can be written.
*/
registerStreamSendEvent(packet, info) {
this.paramWritten = function () {
let flushed = false;
while (!flushed) {
if (this.packet.haveErrorResponse) {
this.sending = false;
this.emit('send_end');
return;
}
if (this.currentParam === this.valueRow.length) {
// all parameters from row are written.
flushed =
packet.writeString(this.parseResults.partList[this.parseResults.partList.length - 2]) ||
flushed;
flushed =
packet.mark(!this.parseResults.reWritable || this.valueIdx === this.values.length) ||
flushed;
if (this.valueIdx < this.values.length) {
// still remaining rows
this.valueRow = this.values[this.valueIdx++];
this.currentParam = 0;
} else {
// all rows are written
this.sending = false;
this.emit('send_end');
return;
}
}
flushed = packet.writeString(this.parseResults.partList[this.currentParam + 1]) || flushed;
const value = this.valueRow[this.currentParam];
if (value === null) {
flushed = packet.writeStringAscii('NULL') || flushed;
this.currentParam++;
continue;
}
if (
typeof value === 'object' &&
typeof value.pipe === 'function' &&
typeof value.read === 'function'
) {
//********************************************
// param is stream,
//********************************************
flushed = packet.writeInt8(QUOTE) || flushed;
value.once(
'end',
function () {
packet.writeInt8(QUOTE);
this.currentParam++;
this.paramWritten();
}.bind(this)
);
value.on('data', function (chunk) {
packet.writeBufferEscape(chunk);
});
return;
}
//********************************************
// param isn't stream. directly write in buffer
//********************************************
flushed = this.writeParam(packet, value, this.opts, info) || flushed;
this.currentParam++;
}
if (this.sending) setImmediate(this.paramWritten.bind(this));
}.bind(this);
}
}
module.exports = BatchRewrite;

149
node_modules/mariadb/lib/cmd/change-user.js generated vendored Normal file
View File

@@ -0,0 +1,149 @@
'use strict';
const Iconv = require('iconv-lite');
const Capabilities = require('../const/capabilities');
const Ed25519PasswordAuth = require('./handshake/auth/ed25519-password-auth');
const NativePasswordAuth = require('./handshake/auth/native-password-auth');
const Collations = require('../const/collations');
const Handshake = require('./handshake/handshake');
/**
* send a COM_CHANGE_USER: resets the connection and re-authenticates with the given credentials
* see https://mariadb.com/kb/en/library/com_change_user/
*/
class ChangeUser extends Handshake {
constructor(options, resolve, reject, addCommand) {
super(resolve, reject, () => {}, addCommand);
this.opts = options;
}
start(out, opts, info) {
this.configAssign(opts, this.opts);
let authToken;
const pwd = Array.isArray(this.opts.password) ? this.opts.password[0] : this.opts.password;
switch (info.defaultPluginName) {
case 'mysql_native_password':
case '':
authToken = NativePasswordAuth.encryptPassword(pwd, info.seed, 'sha1');
break;
case 'client_ed25519':
authToken = Ed25519PasswordAuth.encryptPassword(pwd, info.seed);
break;
default:
authToken = Buffer.alloc(0);
break;
}
out.startPacket(this);
out.writeInt8(0x11);
out.writeString(this.opts.user || '');
out.writeInt8(0);
if (info.serverCapabilities & Capabilities.SECURE_CONNECTION) {
out.writeInt8(authToken.length);
out.writeBuffer(authToken, 0, authToken.length);
} else {
out.writeBuffer(authToken, 0, authToken.length);
out.writeInt8(0);
}
if (info.clientCapabilities & Capabilities.CONNECT_WITH_DB) {
out.writeString(this.opts.database);
out.writeInt8(0);
info.database = this.opts.database;
}
out.writeInt16(this.opts.collation.index);
if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
out.writeString(info.defaultPluginName);
out.writeInt8(0);
}
if (info.clientCapabilities & Capabilities.CONNECT_ATTRS) {
out.writeInt8(0xfc);
let initPos = out.pos; //save position, assuming connection attributes length will be less than 2 bytes length
out.writeInt16(0);
const encoding = this.opts.collation.charset;
writeParam(out, '_client_name', encoding);
writeParam(out, 'MariaDB connector/Node', encoding);
let packageJson = require('../../package.json');
writeParam(out, '_client_version', encoding);
writeParam(out, packageJson.version, encoding);
writeParam(out, '_node_version', encoding);
writeParam(out, process.versions.node, encoding);
if (opts.connectAttributes !== true) {
let attrNames = Object.keys(this.opts.connectAttributes);
for (let k = 0; k < attrNames.length; ++k) {
writeParam(out, attrNames[k], encoding);
writeParam(out, this.opts.connectAttributes[attrNames[k]], encoding);
}
}
//write end size
out.writeInt16AtPos(initPos);
}
out.flushBuffer(true);
this.onPacketReceive = this.handshakeResult;
}
/**
* Assign global configuration option used by result-set to current query option.
* a little faster than Object.assign() since doest copy all information
*
* @param connOpts connection global configuration
* @param opt current options
*/
configAssign(connOpts, opt) {
if (!opt) {
this.opts = connOpts;
return;
}
this.opts.database = opt.database ? opt.database : connOpts.database;
this.opts.connectAttributes = opt.connectAttributes
? opt.connectAttributes
: connOpts.connectAttributes;
if (opt.charset && typeof opt.charset === 'string') {
this.opts.collation = Collations.fromCharset(opt.charset.toLowerCase());
if (this.opts.collation === undefined) {
this.opts.collation = Collations.fromName(opt.charset.toUpperCase());
if (this.opts.collation !== undefined) {
console.log(
"warning: please use option 'collation' " +
"in replacement of 'charset' when using a collation name ('" +
opt.charset +
"')\n" +
"(collation looks like 'UTF8MB4_UNICODE_CI', charset like 'utf8')."
);
}
}
if (this.opts.collation === undefined)
throw new RangeError("Unknown charset '" + opt.charset + "'");
} else if (opt.collation && typeof opt.collation === 'string') {
const initial = opt.collation;
this.opts.collation = Collations.fromName(initial.toUpperCase());
if (this.opts.collation === undefined)
throw new RangeError("Unknown collation '" + initial + "'");
} else {
this.opts.collation = Collations.fromIndex(opt.charsetNumber) || connOpts.collation;
}
connOpts.password = opt.password;
}
}
function writeParam(out, val, encoding) {
let param = Buffer.isEncoding(encoding)
? Buffer.from(val, encoding)
: Iconv.encode(val, encoding);
out.writeLengthCoded(param.length);
out.writeBuffer(param, 0, param.length);
}
module.exports = ChangeUser;

17
node_modules/mariadb/lib/cmd/class/ok-packet.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
'use strict';
const Command = require('../command');
/**
* Ok_Packet
* see https://mariadb.com/kb/en/ok_packet/
*/
class OkPacket {
constructor(affectedRows, insertId, warningStatus) {
this.affectedRows = affectedRows;
this.insertId = insertId;
this.warningStatus = warningStatus;
}
}
module.exports = OkPacket;

102
node_modules/mariadb/lib/cmd/column-definition.js generated vendored Normal file
View File

@@ -0,0 +1,102 @@
'use strict';
const Collations = require('../const/collations.js');
const FieldType = require('../const/field-type');
const Capabilities = require('../const/capabilities');
/**
* Column definition
* see https://mariadb.com/kb/en/library/resultset/#column-definition-packet
*/
class ColumnDef {
constructor(packet, info) {
this._parse = new StringParser(packet);
if (info.serverCapabilities & Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO) {
const subPacket = packet.subPacketLengthEncoded();
while (subPacket.remaining()) {
switch (subPacket.readUInt8()) {
case 0:
this.dataTypeName = subPacket.readAsciiStringLengthEncoded();
break;
case 1:
this.dataTypeFormat = subPacket.readAsciiStringLengthEncoded();
break;
default:
// skip data
const len = subPacket.readUnsignedLength();
if (len) {
subPacket.skip(len);
}
break;
}
}
}
packet.skip(1); // length of fixed fields
this.collation = Collations.fromIndex(packet.readUInt16());
this.columnLength = packet.readUInt32();
this.columnType = packet.readUInt8();
this.flags = packet.readUInt16();
this.scale = packet.readUInt8();
this.type = FieldType.TYPES[this.columnType];
}
db() {
return this._parse.packet.readString(this._parse.dbOffset, this._parse.dbLength);
}
schema() {
return this._parse.packet.readString(this._parse.dbOffset, this._parse.dbLength);
}
table() {
return this._parse.packet.readString(this._parse.tableOffset, this._parse.tableLength);
}
orgTable() {
return this._parse.packet.readString(this._parse.orgTableOffset, this._parse.orgTableLength);
}
name() {
return this._parse.packet.readString(this._parse.nameOffset, this._parse.nameLength);
}
orgName() {
return this._parse.packet.readString(this._parse.orgNameOffset, this._parse.orgNameLength);
}
}
/**
* String parser.
* This object permits to avoid listing all private information to metadata object.
*/
class StringParser {
constructor(packet) {
packet.skip(4); // skip 'def'
this.dbLength = packet.readUnsignedLength();
this.dbOffset = packet.pos;
packet.skip(this.dbLength);
this.tableLength = packet.readUnsignedLength();
this.tableOffset = packet.pos;
packet.skip(this.tableLength);
this.orgTableLength = packet.readUnsignedLength();
this.orgTableOffset = packet.pos;
packet.skip(this.orgTableLength);
this.nameLength = packet.readUnsignedLength();
this.nameOffset = packet.pos;
packet.skip(this.nameLength);
this.orgNameLength = packet.readUnsignedLength();
this.orgNameOffset = packet.pos;
packet.skip(this.orgNameLength);
this.packet = packet;
}
}
module.exports = ColumnDef;

165
node_modules/mariadb/lib/cmd/command.js generated vendored Normal file
View File

@@ -0,0 +1,165 @@
'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;

327
node_modules/mariadb/lib/cmd/common-binary-cmd.js generated vendored Normal file
View File

@@ -0,0 +1,327 @@
'use strict';
const ResultSet = require('./resultset');
class CommonBinary extends ResultSet {
constructor(resolve, reject, cmdOpts, connOpts, sql, values) {
super(resolve, reject);
this.configAssign(connOpts, cmdOpts);
this.sql = sql;
this.initialValues = values;
}
/**
* Write (and escape) current parameter value to output writer
*
* @param out output writer
* @param value current parameter
* @param opts connection options
* @param info connection information
*/
writeParam(out, value, opts, info) {
let flushed = false;
switch (typeof value) {
case 'boolean':
flushed = out.writeInt8(0x00);
flushed = out.writeInt8(value ? 0x01 : 0x00) || flushed;
break;
case 'bigint':
case 'number':
flushed = out.writeInt8(0x00);
flushed = out.writeLengthStringAscii('' + value) || flushed;
break;
case 'object':
if (Object.prototype.toString.call(value) === '[object Date]') {
flushed = out.writeInt8(0x00);
flushed = out.writeBinaryDate(value, opts) || flushed;
} else if (Buffer.isBuffer(value)) {
flushed = out.writeInt8(0x00);
flushed = out.writeLengthEncodedBuffer(value) || flushed;
} else if (typeof value.toSqlString === 'function') {
flushed = out.writeInt8(0x00);
flushed = out.writeLengthEncodedString(String(value.toSqlString())) || flushed;
} else {
if (
value.type != null &&
[
'Point',
'LineString',
'Polygon',
'MultiPoint',
'MultiLineString',
'MultiPolygon',
'GeometryCollection'
].includes(value.type)
) {
const geoBuff = this.getBufferFromGeometryValue(value);
if (geoBuff) {
flushed = out.writeInt8(0x00); //Value follow
flushed =
out.writeLengthEncodedBuffer(Buffer.concat([Buffer.from([0, 0, 0, 0]), geoBuff])) ||
flushed;
} else {
flushed = out.writeInt8(0x01); //NULL
}
} else {
//TODO check if permitSetMultiParamEntries is needed !?
flushed = out.writeInt8(0x00);
flushed = out.writeLengthEncodedString(JSON.stringify(value)) || flushed;
}
}
break;
default:
flushed = out.writeInt8(0x00);
flushed = out.writeLengthEncodedString(value) || flushed;
}
return flushed;
}
getBufferFromGeometryValue(value, headerType) {
let geoBuff;
let pos;
let type;
if (!headerType) {
switch (value.type) {
case 'Point':
geoBuff = Buffer.allocUnsafe(21);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(1, 1); //wkbPoint
if (
value.coordinates &&
Array.isArray(value.coordinates) &&
value.coordinates.length >= 2 &&
!isNaN(value.coordinates[0]) &&
!isNaN(value.coordinates[1])
) {
geoBuff.writeDoubleLE(value.coordinates[0], 5); //X
geoBuff.writeDoubleLE(value.coordinates[1], 13); //Y
return geoBuff;
} else {
return null;
}
case 'LineString':
if (value.coordinates && Array.isArray(value.coordinates)) {
const pointNumber = value.coordinates.length;
geoBuff = Buffer.allocUnsafe(9 + 16 * pointNumber);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(2, 1); //wkbLineString
geoBuff.writeInt32LE(pointNumber, 5);
for (let i = 0; i < pointNumber; i++) {
if (
value.coordinates[i] &&
Array.isArray(value.coordinates[i]) &&
value.coordinates[i].length >= 2 &&
!isNaN(value.coordinates[i][0]) &&
!isNaN(value.coordinates[i][1])
) {
geoBuff.writeDoubleLE(value.coordinates[i][0], 9 + 16 * i); //X
geoBuff.writeDoubleLE(value.coordinates[i][1], 17 + 16 * i); //Y
} else {
return null;
}
}
return geoBuff;
} else {
return null;
}
case 'Polygon':
if (value.coordinates && Array.isArray(value.coordinates)) {
const numRings = value.coordinates.length;
let size = 0;
for (let i = 0; i < numRings; i++) {
size += 4 + 16 * value.coordinates[i].length;
}
geoBuff = Buffer.allocUnsafe(9 + size);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(3, 1); //wkbPolygon
geoBuff.writeInt32LE(numRings, 5);
pos = 9;
for (let i = 0; i < numRings; i++) {
const lineString = value.coordinates[i];
if (lineString && Array.isArray(lineString)) {
geoBuff.writeInt32LE(lineString.length, pos);
pos += 4;
for (let j = 0; j < lineString.length; j++) {
if (
lineString[j] &&
Array.isArray(lineString[j]) &&
lineString[j].length >= 2 &&
!isNaN(lineString[j][0]) &&
!isNaN(lineString[j][1])
) {
geoBuff.writeDoubleLE(lineString[j][0], pos); //X
geoBuff.writeDoubleLE(lineString[j][1], pos + 8); //Y
pos += 16;
} else {
return null;
}
}
}
}
return geoBuff;
} else {
return null;
}
case 'MultiPoint':
type = 'MultiPoint';
geoBuff = Buffer.allocUnsafe(9);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(4, 1); //wkbMultiPoint
break;
case 'MultiLineString':
type = 'MultiLineString';
geoBuff = Buffer.allocUnsafe(9);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(5, 1); //wkbMultiLineString
break;
case 'MultiPolygon':
type = 'MultiPolygon';
geoBuff = Buffer.allocUnsafe(9);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(6, 1); //wkbMultiPolygon
break;
case 'GeometryCollection':
geoBuff = Buffer.allocUnsafe(9);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(7, 1); //wkbGeometryCollection
if (value.geometries && Array.isArray(value.geometries)) {
const coordinateLength = value.geometries.length;
const subArrays = [geoBuff];
for (let i = 0; i < coordinateLength; i++) {
const tmpBuf = this.getBufferFromGeometryValue(value.geometries[i]);
if (tmpBuf == null) break;
subArrays.push(tmpBuf);
}
geoBuff.writeInt32LE(subArrays.length - 1, 5);
return Buffer.concat(subArrays);
} else {
geoBuff.writeInt32LE(0, 5);
return geoBuff;
}
default:
return null;
}
if (value.coordinates && Array.isArray(value.coordinates)) {
const coordinateLength = value.coordinates.length;
const subArrays = [geoBuff];
for (let i = 0; i < coordinateLength; i++) {
const tmpBuf = this.getBufferFromGeometryValue(value.coordinates[i], type);
if (tmpBuf == null) break;
subArrays.push(tmpBuf);
}
geoBuff.writeInt32LE(subArrays.length - 1, 5);
return Buffer.concat(subArrays);
} else {
geoBuff.writeInt32LE(0, 5);
return geoBuff;
}
} else {
switch (headerType) {
case 'MultiPoint':
if (
value &&
Array.isArray(value) &&
value.length >= 2 &&
!isNaN(value[0]) &&
!isNaN(value[1])
) {
geoBuff = Buffer.allocUnsafe(21);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(1, 1); //wkbPoint
geoBuff.writeDoubleLE(value[0], 5); //X
geoBuff.writeDoubleLE(value[1], 13); //Y
return geoBuff;
}
return null;
case 'MultiLineString':
if (value && Array.isArray(value)) {
const pointNumber = value.length;
geoBuff = Buffer.allocUnsafe(9 + 16 * pointNumber);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(2, 1); //wkbLineString
geoBuff.writeInt32LE(pointNumber, 5);
for (let i = 0; i < pointNumber; i++) {
if (
value[i] &&
Array.isArray(value[i]) &&
value[i].length >= 2 &&
!isNaN(value[i][0]) &&
!isNaN(value[i][1])
) {
geoBuff.writeDoubleLE(value[i][0], 9 + 16 * i); //X
geoBuff.writeDoubleLE(value[i][1], 17 + 16 * i); //Y
} else {
return null;
}
}
return geoBuff;
}
return null;
case 'MultiPolygon':
if (value && Array.isArray(value)) {
const numRings = value.length;
let size = 0;
for (let i = 0; i < numRings; i++) {
size += 4 + 16 * value[i].length;
}
geoBuff = Buffer.allocUnsafe(9 + size);
geoBuff.writeInt8(0x01, 0); //LITTLE ENDIAN
geoBuff.writeInt32LE(3, 1); //wkbPolygon
geoBuff.writeInt32LE(numRings, 5);
pos = 9;
for (let i = 0; i < numRings; i++) {
const lineString = value[i];
if (lineString && Array.isArray(lineString)) {
geoBuff.writeInt32LE(lineString.length, pos);
pos += 4;
for (let j = 0; j < lineString.length; j++) {
if (
lineString[j] &&
Array.isArray(lineString[j]) &&
lineString[j].length >= 2 &&
!isNaN(lineString[j][0]) &&
!isNaN(lineString[j][1])
) {
geoBuff.writeDoubleLE(lineString[j][0], pos); //X
geoBuff.writeDoubleLE(lineString[j][1], pos + 8); //Y
pos += 16;
} else {
return null;
}
}
}
}
return geoBuff;
}
return null;
}
return null;
}
}
/**
* Read text result-set row
*
* see: https://mariadb.com/kb/en/library/resultset-row/#text-resultset-row
* data are created according to their type.
*
* @param columns columns metadata
* @param packet current row packet
* @param connOpts connection options
* @returns {*} row data
*/
parseRow(columns, packet, connOpts) {
throw new Error('not implemented');
}
}
module.exports = CommonBinary;

427
node_modules/mariadb/lib/cmd/common-text-cmd.js generated vendored Normal file
View File

@@ -0,0 +1,427 @@
'use strict';
const ResultSet = require('./resultset');
const FieldDetail = require('../const/field-detail');
const FieldType = require('../const/field-type');
const Long = require('long');
const moment = require('moment-timezone');
const QUOTE = 0x27;
class CommonText extends ResultSet {
constructor(resolve, reject, cmdOpts, connOpts, sql, values) {
super(resolve, reject);
this.configAssign(connOpts, cmdOpts);
this.sql = sql;
this.initialValues = values;
this.getDateQuote = this.opts.tz
? this.opts.tz === 'Etc/UTC'
? CommonText.getUtcDate
: CommonText.getTimezoneDate
: CommonText.getLocalDate;
}
/**
* Write (and escape) current parameter value to output writer
*
* @param out output writer
* @param value current parameter
* @param opts connection options
* @param info connection information
*/
writeParam(out, value, opts, info) {
switch (typeof value) {
case 'boolean':
out.writeStringAscii(value ? 'true' : 'false');
break;
case 'bigint':
case 'number':
out.writeStringAscii('' + value);
break;
case 'object':
if (value === null) {
out.writeStringAscii('NULL');
} else if (Object.prototype.toString.call(value) === '[object Date]') {
out.writeStringAscii(this.getDateQuote(value, opts));
} else if (Buffer.isBuffer(value)) {
out.writeStringAscii("_BINARY '");
out.writeBufferEscape(value);
out.writeInt8(QUOTE);
} else if (typeof value.toSqlString === 'function') {
out.writeStringEscapeQuote(String(value.toSqlString()));
} else if (Long.isLong(value)) {
out.writeStringAscii(value.toString());
} else if (Array.isArray(value)) {
if (opts.arrayParenthesis) {
out.writeStringAscii('(');
}
for (let i = 0; i < value.length; i++) {
if (i !== 0) out.writeStringAscii(',');
this.writeParam(out, value[i], opts, info);
}
if (opts.arrayParenthesis) {
out.writeStringAscii(')');
}
} else {
if (
value.type != null &&
[
'Point',
'LineString',
'Polygon',
'MultiPoint',
'MultiLineString',
'MultiPolygon',
'GeometryCollection'
].includes(value.type)
) {
//GeoJSON format.
let prefix =
(info.isMariaDB() && info.hasMinVersion(10, 1, 4)) ||
(!info.isMariaDB() && info.hasMinVersion(5, 7, 6))
? 'ST_'
: '';
switch (value.type) {
case 'Point':
out.writeStringAscii(
prefix +
"PointFromText('POINT(" +
CommonText.geoPointToString(value.coordinates) +
")')"
);
break;
case 'LineString':
out.writeStringAscii(
prefix +
"LineFromText('LINESTRING(" +
CommonText.geoArrayPointToString(value.coordinates) +
")')"
);
break;
case 'Polygon':
out.writeStringAscii(
prefix +
"PolygonFromText('POLYGON(" +
CommonText.geoMultiArrayPointToString(value.coordinates) +
")')"
);
break;
case 'MultiPoint':
out.writeStringAscii(
prefix +
"MULTIPOINTFROMTEXT('MULTIPOINT(" +
CommonText.geoArrayPointToString(value.coordinates) +
")')"
);
break;
case 'MultiLineString':
out.writeStringAscii(
prefix +
"MLineFromText('MULTILINESTRING(" +
CommonText.geoMultiArrayPointToString(value.coordinates) +
")')"
);
break;
case 'MultiPolygon':
out.writeStringAscii(
prefix +
"MPolyFromText('MULTIPOLYGON(" +
CommonText.geoMultiPolygonToString(value.coordinates) +
")')"
);
break;
case 'GeometryCollection':
out.writeStringAscii(
prefix +
"GeomCollFromText('GEOMETRYCOLLECTION(" +
CommonText.geometricCollectionToString(value.geometries) +
")')"
);
break;
}
} else {
if (opts.permitSetMultiParamEntries) {
let first = true;
for (let key in value) {
const val = value[key];
if (typeof val === 'function') continue;
if (first) {
first = false;
} else {
out.writeStringAscii(',');
}
out.writeString('`' + key + '`');
out.writeStringAscii('=');
this.writeParam(out, val, opts, info);
}
if (first) out.writeStringEscapeQuote(JSON.stringify(value));
} else {
out.writeStringEscapeQuote(JSON.stringify(value));
}
}
}
break;
default:
out.writeStringEscapeQuote(value);
}
}
static geometricCollectionToString(geo) {
if (!geo) return '';
let st = '';
for (let i = 0; i < geo.length; i++) {
//GeoJSON format.
st += i !== 0 ? ',' : '';
switch (geo[i].type) {
case 'Point':
st += 'POINT(' + CommonText.geoPointToString(geo[i].coordinates) + ')';
break;
case 'LineString':
st += 'LINESTRING(' + CommonText.geoArrayPointToString(geo[i].coordinates) + ')';
break;
case 'Polygon':
st += 'POLYGON(' + CommonText.geoMultiArrayPointToString(geo[i].coordinates) + ')';
break;
case 'MultiPoint':
st += 'MULTIPOINT(' + CommonText.geoArrayPointToString(geo[i].coordinates) + ')';
break;
case 'MultiLineString':
st +=
'MULTILINESTRING(' + CommonText.geoMultiArrayPointToString(geo[i].coordinates) + ')';
break;
case 'MultiPolygon':
st += 'MULTIPOLYGON(' + CommonText.geoMultiPolygonToString(geo[i].coordinates) + ')';
break;
}
}
return st;
}
static geoMultiPolygonToString(coords) {
if (!coords) return '';
let st = '';
for (let i = 0; i < coords.length; i++) {
st += (i !== 0 ? ',(' : '(') + CommonText.geoMultiArrayPointToString(coords[i]) + ')';
}
return st;
}
static geoMultiArrayPointToString(coords) {
if (!coords) return '';
let st = '';
for (let i = 0; i < coords.length; i++) {
st += (i !== 0 ? ',(' : '(') + CommonText.geoArrayPointToString(coords[i]) + ')';
}
return st;
}
static geoArrayPointToString(coords) {
if (!coords) return '';
let st = '';
for (let i = 0; i < coords.length; i++) {
st += (i !== 0 ? ',' : '') + CommonText.geoPointToString(coords[i]);
}
return st;
}
static geoPointToString(coords) {
if (!coords) return '';
return (isNaN(coords[0]) ? '' : coords[0]) + ' ' + (isNaN(coords[1]) ? '' : coords[1]);
}
parseRowAsArray(columns, packet, connOpts) {
const row = new Array(this._columnCount);
for (let i = 0; i < this._columnCount; i++) {
row[i] = this._getValue(i, columns[i], this.opts, connOpts, packet);
}
return row;
}
parseRowNested(columns, packet, connOpts) {
const row = {};
for (let i = 0; i < this._columnCount; i++) {
if (!row[this.tableHeader[i][0]]) row[this.tableHeader[i][0]] = {};
row[this.tableHeader[i][0]][this.tableHeader[i][1]] = this._getValue(
i,
columns[i],
this.opts,
connOpts,
packet
);
}
return row;
}
parseRowStd(columns, packet, connOpts) {
const row = {};
for (let i = 0; i < this._columnCount; i++) {
row[this.tableHeader[i]] = this._getValue(i, columns[i], this.opts, connOpts, packet);
}
return row;
}
castTextWrapper(column, opts, connOpts, packet) {
column.string = () => packet.readStringLength();
column.buffer = () => packet.readBufferLengthEncoded();
column.float = () => packet.readFloatLengthCoded();
column.int = () => packet.readIntLengthEncoded();
column.long = () =>
packet.readLongLengthEncoded(
opts.supportBigInt,
opts.supportBigNumbers,
opts.bigNumberStrings,
(column.flags & FieldDetail.UNSIGNED) > 0
);
column.decimal = () => packet.readDecimalLengthEncoded(opts.bigNumberStrings);
column.date = () => packet.readDateTime(opts);
column.geometry = () => {
return column.readGeometry();
};
}
readCastValue(index, column, opts, connOpts, packet) {
this.castTextWrapper(column, opts, connOpts, packet);
return opts.typeCast(
column,
this.readRowData.bind(this, index, column, opts, connOpts, packet)
);
}
/**
* Read row data.
*
* @param index current data index in row
* @param column associate metadata
* @param opts query options
* @param connOpts connection options
* @param packet row packet
* @returns {*} data
*/
readRowData(index, column, opts, connOpts, packet) {
switch (column.columnType) {
case FieldType.TINY:
case FieldType.SHORT:
case FieldType.LONG:
case FieldType.INT24:
case FieldType.YEAR:
return packet.readIntLengthEncoded();
case FieldType.FLOAT:
case FieldType.DOUBLE:
return packet.readFloatLengthCoded();
case FieldType.LONGLONG:
return packet.readLongLengthEncoded(
opts.supportBigInt,
opts.supportBigNumbers,
opts.bigNumberStrings,
(column.flags & FieldDetail.UNSIGNED) > 0
);
case FieldType.DECIMAL:
case FieldType.NEWDECIMAL:
return packet.readDecimalLengthEncoded(opts.bigNumberStrings);
case FieldType.DATE:
if (opts.dateStrings) {
return packet.readAsciiStringLengthEncoded();
}
return packet.readDate();
case FieldType.DATETIME:
case FieldType.TIMESTAMP:
if (opts.dateStrings) {
return packet.readAsciiStringLengthEncoded();
}
return packet.readDateTime(opts);
case FieldType.TIME:
return packet.readAsciiStringLengthEncoded();
case FieldType.GEOMETRY:
return packet.readGeometry(column.dataTypeName);
case FieldType.JSON:
//for mysql only => parse string as JSON object
return JSON.parse(packet.readStringLengthEncoded('utf8'));
default:
if (column.dataTypeFormat && column.dataTypeFormat === 'json' && opts.autoJsonMap) {
return JSON.parse(packet.readStringLengthEncoded('utf8'));
}
if (column.collation.index === 63) {
return packet.readBufferLengthEncoded();
}
const string = packet.readStringLength();
if (column.flags & 2048) {
//SET
return string == null ? null : string === '' ? [] : string.split(',');
}
return string;
}
}
}
function getDatePartQuote(year, mon, day, hour, min, sec, ms) {
//return 'YYYY-MM-DD HH:MM:SS' datetime format
//see https://mariadb.com/kb/en/library/datetime/
return (
"'" +
(year > 999 ? year : year > 99 ? '0' + year : year > 9 ? '00' + year : '000' + year) +
'-' +
(mon < 10 ? '0' : '') +
mon +
'-' +
(day < 10 ? '0' : '') +
day +
' ' +
(hour < 10 ? '0' : '') +
hour +
':' +
(min < 10 ? '0' : '') +
min +
':' +
(sec < 10 ? '0' : '') +
sec +
'.' +
(ms > 99 ? ms : ms > 9 ? '0' + ms : '00' + ms) +
"'"
);
}
function getLocalDate(date, opts) {
const year = date.getFullYear();
const mon = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const min = date.getMinutes();
const sec = date.getSeconds();
const ms = date.getMilliseconds();
return getDatePartQuote(year, mon, day, hour, min, sec, ms);
}
function getUtcDate(date, opts) {
const year = date.getUTCFullYear();
const mon = date.getUTCMonth() + 1;
const day = date.getUTCDate();
const hour = date.getUTCHours();
const min = date.getUTCMinutes();
const sec = date.getUTCSeconds();
const ms = date.getUTCMilliseconds();
return getDatePartQuote(year, mon, day, hour, min, sec, ms);
}
function getTimezoneDate(date, opts) {
if (date.getMilliseconds() != 0) {
return moment.tz(date, opts.tz).format("'YYYY-MM-DD HH:mm:ss.SSS'");
}
return moment.tz(date, opts.tz).format("'YYYY-MM-DD HH:mm:ss'");
}
module.exports = CommonText;
module.exports.getTimezoneDate = getTimezoneDate;
module.exports.getUtcDate = getUtcDate;
module.exports.getLocalDate = getLocalDate;

View File

@@ -0,0 +1,167 @@
const PluginAuth = require('./plugin-auth');
const fs = require('fs');
const crypto = require('crypto');
const Errors = require('../../../misc/errors');
const NativePasswordAuth = require('./native-password-auth');
const Sha256PasswordAuth = require('./sha256-password-auth');
const State = {
INIT: 'INIT',
FAST_AUTH_RESULT: 'FAST_AUTH_RESULT',
REQUEST_SERVER_KEY: 'REQUEST_SERVER_KEY',
SEND_AUTH: 'SEND_AUTH'
};
/**
* Use caching Sha2 password authentication
*/
class CachingSha2PasswordAuth extends PluginAuth {
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
super(resolve, reject, multiAuthResolver);
this.pluginData = pluginData;
this.sequenceNo = packSeq;
this.counter = 0;
this.state = State.INIT;
}
start(out, opts, info) {
this.exchange(this.pluginData, out, opts, info);
this.onPacketReceive = this.response;
}
exchange(buffer, out, opts, info) {
switch (this.state) {
case State.INIT:
const truncatedSeed = this.pluginData.slice(0, this.pluginData.length - 1);
const encPwd = NativePasswordAuth.encryptPassword(opts.password, truncatedSeed, 'sha256');
out.startPacket(this);
if (encPwd.length > 0) {
out.writeBuffer(encPwd, 0, encPwd.length);
out.flushBuffer(true);
} else {
out.writeEmptyPacket(true);
}
this.state = State.FAST_AUTH_RESULT;
return;
case State.FAST_AUTH_RESULT:
// length encoded numeric : 0x01 0x03/0x04
const fastAuthResult = buffer[1];
switch (fastAuthResult) {
case 0x03:
// success authentication
this.emit('send_end');
return this.successSend(packet, out, opts, info);
case 0x04:
if (opts.ssl) {
// using SSL, so sending password in clear
out.startPacket(this);
out.writeString(opts.password);
out.writeInt8(0);
out.flushBuffer(true);
return;
}
// retrieve public key from configuration or from server
if (opts.cachingRsaPublicKey) {
try {
let key = opts.cachingRsaPublicKey;
if (!key.includes('-----BEGIN')) {
// rsaPublicKey contain path
key = fs.readFileSync(key, 'utf8');
}
this.publicKey = Sha256PasswordAuth.retreivePublicKey(key);
} catch (err) {
return this.throwError(err, info);
}
// send Sha256Password Packet
Sha256PasswordAuth.sendSha256PwdPacket(
this,
this.pluginData,
this.publicKey,
opts.password,
out
);
} else {
if (!opts.allowPublicKeyRetrieval) {
return this.throwError(
Errors.createError(
'RSA public key is not available client side. Either set option `cachingRsaPublicKey` to indicate' +
' public key path, or allow public key retrieval with option `allowPublicKeyRetrieval`',
true,
info,
'08S01',
Errors.ER_CANNOT_RETRIEVE_RSA_KEY
),
info
);
}
this.state = State.REQUEST_SERVER_KEY;
// ask caching public Key Retrieval
out.startPacket(this);
out.writeInt8(0x02);
out.flushBuffer(true);
}
return;
}
case State.REQUEST_SERVER_KEY:
this.publicKey = Sha256PasswordAuth.retreivePublicKey(buffer.toString('utf8', 1));
this.state = State.SEND_AUTH;
Sha256PasswordAuth.sendSha256PwdPacket(
this,
this.pluginData,
this.publicKey,
opts.password,
out
);
}
}
static retreivePublicKey(key) {
return key.replace('(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)', '');
}
static sendSha256PwdPacket(cmd, pluginData, publicKey, password, out) {
const truncatedSeed = pluginData.slice(0, pluginData.length - 1);
out.startPacket(cmd);
const enc = Sha256PasswordAuth.encrypt(truncatedSeed, password, publicKey);
out.writeBuffer(enc, 0, enc.length);
out.flushBuffer(cmd);
}
// encrypt password with public key
static encrypt(seed, password, publicKey) {
const nullFinishedPwd = Buffer.from(password + '\0');
const xorBytes = Buffer.allocUnsafe(nullFinishedPwd.length);
const seedLength = seed.length;
for (let i = 0; i < xorBytes.length; i++) {
xorBytes[i] = nullFinishedPwd[i] ^ seed[i % seedLength];
}
return crypto.publicEncrypt(
{ key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
xorBytes
);
}
response(packet, out, opts, info) {
const marker = packet.peek();
switch (marker) {
//*********************************************************************************************************
//* OK_Packet and Err_Packet ending packet
//*********************************************************************************************************
case 0x00:
case 0xff:
this.emit('send_end');
return this.successSend(packet, out, opts, info);
default:
let promptData = packet.readBufferRemaining();
this.exchange(promptData, out, opts, info);
this.onPacketReceive = this.response;
}
}
}
module.exports = CachingSha2PasswordAuth;

View File

@@ -0,0 +1,23 @@
const PluginAuth = require('./plugin-auth');
/**
* Send password in clear.
* (used only when SSL is active)
*/
class ClearPasswordAuth extends PluginAuth {
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
super(resolve, reject, multiAuthResolver);
this.sequenceNo = packSeq;
}
start(out, opts, info) {
out.startPacket(this);
if (opts.password) out.writeString(opts.password);
out.writeInt8(0);
out.flushBuffer(true);
this.emit('send_end');
this.onPacketReceive = this.successSend;
}
}
module.exports = ClearPasswordAuth;

View File

@@ -0,0 +1,833 @@
'use strict';
const PluginAuth = require('./plugin-auth');
const Crypto = require('crypto');
/**
* Standard authentication plugin
*/
class Ed25519PasswordAuth extends PluginAuth {
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
super(resolve, reject, multiAuthResolver);
this.pluginData = pluginData;
this.sequenceNo = packSeq;
}
start(out, opts, info) {
//seed is ended with a null byte value.
const data = this.pluginData;
const sign = Ed25519PasswordAuth.encryptPassword(opts.password, data);
out.startPacket(this);
out.writeBuffer(sign, 0, sign.length);
out.flushBuffer(true);
this.emit('send_end');
this.onPacketReceive = this.successSend;
}
static encryptPassword(password, seed) {
if (!password) return Buffer.alloc(0);
let i, j;
let p = [gf(), gf(), gf(), gf()];
const signedMsg = Buffer.alloc(96);
const bytePwd = Buffer.from(password);
let hash = Crypto.createHash('sha512');
const d = hash.update(bytePwd).digest();
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
for (i = 0; i < 32; i++) signedMsg[64 + i] = seed[i];
for (i = 0; i < 32; i++) signedMsg[32 + i] = d[32 + i];
hash = Crypto.createHash('sha512');
const r = hash.update(signedMsg.slice(32, 96)).digest();
reduce(r);
scalarbase(p, r);
pack(signedMsg, p);
p = [gf(), gf(), gf(), gf()];
scalarbase(p, d);
const tt = Buffer.alloc(32);
pack(tt, p);
for (i = 32; i < 64; i++) signedMsg[i] = tt[i - 32];
hash = Crypto.createHash('sha512');
const h = hash.update(signedMsg).digest();
reduce(h);
const x = new Float64Array(64);
for (i = 0; i < 64; i++) x[i] = 0;
for (i = 0; i < 32; i++) x[i] = r[i];
for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) {
x[i + j] += h[i] * d[j];
}
}
modL(signedMsg.subarray(32), x);
return signedMsg.slice(0, 64);
}
}
/*******************************************************
*
* This plugin uses the following public domain tweetnacl-js code by Dmitry Chestnykh (from https://github.com/dchest/tweetnacl-js/blob/master/nacl-fast.js).
* tweetnacl cannot be used directly (secret key mandatory size is 32 in nacl + implementation differ : second scalarbase use hash of secret key, not secret key).
*
*******************************************************/
const gf = function (init) {
const r = new Float64Array(16);
if (init) for (let i = 0; i < init.length; i++) r[i] = init[i];
return r;
};
const gf0 = gf(),
gf1 = gf([1]),
D2 = gf([
0xf159,
0x26b2,
0x9b94,
0xebd6,
0xb156,
0x8283,
0x149a,
0x00e0,
0xd130,
0xeef3,
0x80f2,
0x198e,
0xfce7,
0x56df,
0xd9dc,
0x2406
]),
X = gf([
0xd51a,
0x8f25,
0x2d60,
0xc956,
0xa7b2,
0x9525,
0xc760,
0x692c,
0xdc5c,
0xfdd6,
0xe231,
0xc0a4,
0x53fe,
0xcd6e,
0x36d3,
0x2169
]),
Y = gf([
0x6658,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666,
0x6666
]);
const L = new Float64Array([
0xed,
0xd3,
0xf5,
0x5c,
0x1a,
0x63,
0x12,
0x58,
0xd6,
0x9c,
0xf7,
0xa2,
0xde,
0xf9,
0xde,
0x14,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x10
]);
function reduce(r) {
const x = new Float64Array(64);
let i;
for (i = 0; i < 64; i++) x[i] = r[i];
for (i = 0; i < 64; i++) r[i] = 0;
modL(r, x);
}
function modL(r, x) {
let carry, i, j, k;
for (i = 63; i >= 32; --i) {
carry = 0;
for (j = i - 32, k = i - 12; j < k; ++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
carry = (x[j] + 128) >> 8;
x[j] -= carry * 256;
}
x[j] += carry;
x[i] = 0;
}
carry = 0;
for (j = 0; j < 32; j++) {
x[j] += carry - (x[31] >> 4) * L[j];
carry = x[j] >> 8;
x[j] &= 255;
}
for (j = 0; j < 32; j++) x[j] -= carry * L[j];
for (i = 0; i < 32; i++) {
x[i + 1] += x[i] >> 8;
r[i] = x[i] & 255;
}
}
function scalarbase(p, s) {
const q = [gf(), gf(), gf(), gf()];
set25519(q[0], X);
set25519(q[1], Y);
set25519(q[2], gf1);
M(q[3], X, Y);
scalarmult(p, q, s);
}
function set25519(r, a) {
for (let i = 0; i < 16; i++) r[i] = a[i] | 0;
}
function M(o, a, b) {
let v,
c,
t0 = 0,
t1 = 0,
t2 = 0,
t3 = 0,
t4 = 0,
t5 = 0,
t6 = 0,
t7 = 0,
t8 = 0,
t9 = 0,
t10 = 0,
t11 = 0,
t12 = 0,
t13 = 0,
t14 = 0,
t15 = 0,
t16 = 0,
t17 = 0,
t18 = 0,
t19 = 0,
t20 = 0,
t21 = 0,
t22 = 0,
t23 = 0,
t24 = 0,
t25 = 0,
t26 = 0,
t27 = 0,
t28 = 0,
t29 = 0,
t30 = 0;
const b0 = b[0],
b1 = b[1],
b2 = b[2],
b3 = b[3],
b4 = b[4],
b5 = b[5],
b6 = b[6],
b7 = b[7],
b8 = b[8],
b9 = b[9],
b10 = b[10],
b11 = b[11],
b12 = b[12],
b13 = b[13],
b14 = b[14],
b15 = b[15];
v = a[0];
t0 += v * b0;
t1 += v * b1;
t2 += v * b2;
t3 += v * b3;
t4 += v * b4;
t5 += v * b5;
t6 += v * b6;
t7 += v * b7;
t8 += v * b8;
t9 += v * b9;
t10 += v * b10;
t11 += v * b11;
t12 += v * b12;
t13 += v * b13;
t14 += v * b14;
t15 += v * b15;
v = a[1];
t1 += v * b0;
t2 += v * b1;
t3 += v * b2;
t4 += v * b3;
t5 += v * b4;
t6 += v * b5;
t7 += v * b6;
t8 += v * b7;
t9 += v * b8;
t10 += v * b9;
t11 += v * b10;
t12 += v * b11;
t13 += v * b12;
t14 += v * b13;
t15 += v * b14;
t16 += v * b15;
v = a[2];
t2 += v * b0;
t3 += v * b1;
t4 += v * b2;
t5 += v * b3;
t6 += v * b4;
t7 += v * b5;
t8 += v * b6;
t9 += v * b7;
t10 += v * b8;
t11 += v * b9;
t12 += v * b10;
t13 += v * b11;
t14 += v * b12;
t15 += v * b13;
t16 += v * b14;
t17 += v * b15;
v = a[3];
t3 += v * b0;
t4 += v * b1;
t5 += v * b2;
t6 += v * b3;
t7 += v * b4;
t8 += v * b5;
t9 += v * b6;
t10 += v * b7;
t11 += v * b8;
t12 += v * b9;
t13 += v * b10;
t14 += v * b11;
t15 += v * b12;
t16 += v * b13;
t17 += v * b14;
t18 += v * b15;
v = a[4];
t4 += v * b0;
t5 += v * b1;
t6 += v * b2;
t7 += v * b3;
t8 += v * b4;
t9 += v * b5;
t10 += v * b6;
t11 += v * b7;
t12 += v * b8;
t13 += v * b9;
t14 += v * b10;
t15 += v * b11;
t16 += v * b12;
t17 += v * b13;
t18 += v * b14;
t19 += v * b15;
v = a[5];
t5 += v * b0;
t6 += v * b1;
t7 += v * b2;
t8 += v * b3;
t9 += v * b4;
t10 += v * b5;
t11 += v * b6;
t12 += v * b7;
t13 += v * b8;
t14 += v * b9;
t15 += v * b10;
t16 += v * b11;
t17 += v * b12;
t18 += v * b13;
t19 += v * b14;
t20 += v * b15;
v = a[6];
t6 += v * b0;
t7 += v * b1;
t8 += v * b2;
t9 += v * b3;
t10 += v * b4;
t11 += v * b5;
t12 += v * b6;
t13 += v * b7;
t14 += v * b8;
t15 += v * b9;
t16 += v * b10;
t17 += v * b11;
t18 += v * b12;
t19 += v * b13;
t20 += v * b14;
t21 += v * b15;
v = a[7];
t7 += v * b0;
t8 += v * b1;
t9 += v * b2;
t10 += v * b3;
t11 += v * b4;
t12 += v * b5;
t13 += v * b6;
t14 += v * b7;
t15 += v * b8;
t16 += v * b9;
t17 += v * b10;
t18 += v * b11;
t19 += v * b12;
t20 += v * b13;
t21 += v * b14;
t22 += v * b15;
v = a[8];
t8 += v * b0;
t9 += v * b1;
t10 += v * b2;
t11 += v * b3;
t12 += v * b4;
t13 += v * b5;
t14 += v * b6;
t15 += v * b7;
t16 += v * b8;
t17 += v * b9;
t18 += v * b10;
t19 += v * b11;
t20 += v * b12;
t21 += v * b13;
t22 += v * b14;
t23 += v * b15;
v = a[9];
t9 += v * b0;
t10 += v * b1;
t11 += v * b2;
t12 += v * b3;
t13 += v * b4;
t14 += v * b5;
t15 += v * b6;
t16 += v * b7;
t17 += v * b8;
t18 += v * b9;
t19 += v * b10;
t20 += v * b11;
t21 += v * b12;
t22 += v * b13;
t23 += v * b14;
t24 += v * b15;
v = a[10];
t10 += v * b0;
t11 += v * b1;
t12 += v * b2;
t13 += v * b3;
t14 += v * b4;
t15 += v * b5;
t16 += v * b6;
t17 += v * b7;
t18 += v * b8;
t19 += v * b9;
t20 += v * b10;
t21 += v * b11;
t22 += v * b12;
t23 += v * b13;
t24 += v * b14;
t25 += v * b15;
v = a[11];
t11 += v * b0;
t12 += v * b1;
t13 += v * b2;
t14 += v * b3;
t15 += v * b4;
t16 += v * b5;
t17 += v * b6;
t18 += v * b7;
t19 += v * b8;
t20 += v * b9;
t21 += v * b10;
t22 += v * b11;
t23 += v * b12;
t24 += v * b13;
t25 += v * b14;
t26 += v * b15;
v = a[12];
t12 += v * b0;
t13 += v * b1;
t14 += v * b2;
t15 += v * b3;
t16 += v * b4;
t17 += v * b5;
t18 += v * b6;
t19 += v * b7;
t20 += v * b8;
t21 += v * b9;
t22 += v * b10;
t23 += v * b11;
t24 += v * b12;
t25 += v * b13;
t26 += v * b14;
t27 += v * b15;
v = a[13];
t13 += v * b0;
t14 += v * b1;
t15 += v * b2;
t16 += v * b3;
t17 += v * b4;
t18 += v * b5;
t19 += v * b6;
t20 += v * b7;
t21 += v * b8;
t22 += v * b9;
t23 += v * b10;
t24 += v * b11;
t25 += v * b12;
t26 += v * b13;
t27 += v * b14;
t28 += v * b15;
v = a[14];
t14 += v * b0;
t15 += v * b1;
t16 += v * b2;
t17 += v * b3;
t18 += v * b4;
t19 += v * b5;
t20 += v * b6;
t21 += v * b7;
t22 += v * b8;
t23 += v * b9;
t24 += v * b10;
t25 += v * b11;
t26 += v * b12;
t27 += v * b13;
t28 += v * b14;
t29 += v * b15;
v = a[15];
t15 += v * b0;
t16 += v * b1;
t17 += v * b2;
t18 += v * b3;
t19 += v * b4;
t20 += v * b5;
t21 += v * b6;
t22 += v * b7;
t23 += v * b8;
t24 += v * b9;
t25 += v * b10;
t26 += v * b11;
t27 += v * b12;
t28 += v * b13;
t29 += v * b14;
t30 += v * b15;
t0 += 38 * t16;
t1 += 38 * t17;
t2 += 38 * t18;
t3 += 38 * t19;
t4 += 38 * t20;
t5 += 38 * t21;
t6 += 38 * t22;
t7 += 38 * t23;
t8 += 38 * t24;
t9 += 38 * t25;
t10 += 38 * t26;
t11 += 38 * t27;
t12 += 38 * t28;
t13 += 38 * t29;
t14 += 38 * t30;
// t15 left as is
// first car
c = 1;
v = t0 + c + 65535;
c = Math.floor(v / 65536);
t0 = v - c * 65536;
v = t1 + c + 65535;
c = Math.floor(v / 65536);
t1 = v - c * 65536;
v = t2 + c + 65535;
c = Math.floor(v / 65536);
t2 = v - c * 65536;
v = t3 + c + 65535;
c = Math.floor(v / 65536);
t3 = v - c * 65536;
v = t4 + c + 65535;
c = Math.floor(v / 65536);
t4 = v - c * 65536;
v = t5 + c + 65535;
c = Math.floor(v / 65536);
t5 = v - c * 65536;
v = t6 + c + 65535;
c = Math.floor(v / 65536);
t6 = v - c * 65536;
v = t7 + c + 65535;
c = Math.floor(v / 65536);
t7 = v - c * 65536;
v = t8 + c + 65535;
c = Math.floor(v / 65536);
t8 = v - c * 65536;
v = t9 + c + 65535;
c = Math.floor(v / 65536);
t9 = v - c * 65536;
v = t10 + c + 65535;
c = Math.floor(v / 65536);
t10 = v - c * 65536;
v = t11 + c + 65535;
c = Math.floor(v / 65536);
t11 = v - c * 65536;
v = t12 + c + 65535;
c = Math.floor(v / 65536);
t12 = v - c * 65536;
v = t13 + c + 65535;
c = Math.floor(v / 65536);
t13 = v - c * 65536;
v = t14 + c + 65535;
c = Math.floor(v / 65536);
t14 = v - c * 65536;
v = t15 + c + 65535;
c = Math.floor(v / 65536);
t15 = v - c * 65536;
t0 += c - 1 + 37 * (c - 1);
// second car
c = 1;
v = t0 + c + 65535;
c = Math.floor(v / 65536);
t0 = v - c * 65536;
v = t1 + c + 65535;
c = Math.floor(v / 65536);
t1 = v - c * 65536;
v = t2 + c + 65535;
c = Math.floor(v / 65536);
t2 = v - c * 65536;
v = t3 + c + 65535;
c = Math.floor(v / 65536);
t3 = v - c * 65536;
v = t4 + c + 65535;
c = Math.floor(v / 65536);
t4 = v - c * 65536;
v = t5 + c + 65535;
c = Math.floor(v / 65536);
t5 = v - c * 65536;
v = t6 + c + 65535;
c = Math.floor(v / 65536);
t6 = v - c * 65536;
v = t7 + c + 65535;
c = Math.floor(v / 65536);
t7 = v - c * 65536;
v = t8 + c + 65535;
c = Math.floor(v / 65536);
t8 = v - c * 65536;
v = t9 + c + 65535;
c = Math.floor(v / 65536);
t9 = v - c * 65536;
v = t10 + c + 65535;
c = Math.floor(v / 65536);
t10 = v - c * 65536;
v = t11 + c + 65535;
c = Math.floor(v / 65536);
t11 = v - c * 65536;
v = t12 + c + 65535;
c = Math.floor(v / 65536);
t12 = v - c * 65536;
v = t13 + c + 65535;
c = Math.floor(v / 65536);
t13 = v - c * 65536;
v = t14 + c + 65535;
c = Math.floor(v / 65536);
t14 = v - c * 65536;
v = t15 + c + 65535;
c = Math.floor(v / 65536);
t15 = v - c * 65536;
t0 += c - 1 + 37 * (c - 1);
o[0] = t0;
o[1] = t1;
o[2] = t2;
o[3] = t3;
o[4] = t4;
o[5] = t5;
o[6] = t6;
o[7] = t7;
o[8] = t8;
o[9] = t9;
o[10] = t10;
o[11] = t11;
o[12] = t12;
o[13] = t13;
o[14] = t14;
o[15] = t15;
}
function scalarmult(p, q, s) {
let b, i;
set25519(p[0], gf0);
set25519(p[1], gf1);
set25519(p[2], gf1);
set25519(p[3], gf0);
for (i = 255; i >= 0; --i) {
b = (s[(i / 8) | 0] >> (i & 7)) & 1;
cswap(p, q, b);
add(q, p);
add(p, p);
cswap(p, q, b);
}
}
function pack(r, p) {
const tx = gf(),
ty = gf(),
zi = gf();
inv25519(zi, p[2]);
M(tx, p[0], zi);
M(ty, p[1], zi);
pack25519(r, ty);
r[31] ^= par25519(tx) << 7;
}
function inv25519(o, i) {
const c = gf();
let a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) {
S(c, c);
if (a !== 2 && a !== 4) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function S(o, a) {
M(o, a, a);
}
function par25519(a) {
const d = new Uint8Array(32);
pack25519(d, a);
return d[0] & 1;
}
function car25519(o) {
let i,
v,
c = 1;
for (i = 0; i < 16; i++) {
v = o[i] + c + 65535;
c = Math.floor(v / 65536);
o[i] = v - c * 65536;
}
o[0] += c - 1 + 37 * (c - 1);
}
function pack25519(o, n) {
let i, j, b;
const m = gf(),
t = gf();
for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t);
car25519(t);
car25519(t);
for (j = 0; j < 2; j++) {
m[0] = t[0] - 0xffed;
for (i = 1; i < 15; i++) {
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
m[i - 1] &= 0xffff;
}
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
b = (m[15] >> 16) & 1;
m[14] &= 0xffff;
sel25519(t, m, 1 - b);
}
for (i = 0; i < 16; i++) {
o[2 * i] = t[i] & 0xff;
o[2 * i + 1] = t[i] >> 8;
}
}
function cswap(p, q, b) {
for (let i = 0; i < 4; i++) {
sel25519(p[i], q[i], b);
}
}
function A(o, a, b) {
for (let i = 0; i < 16; i++) o[i] = a[i] + b[i];
}
function Z(o, a, b) {
for (let i = 0; i < 16; i++) o[i] = a[i] - b[i];
}
function add(p, q) {
const a = gf(),
b = gf(),
c = gf(),
d = gf(),
e = gf(),
f = gf(),
g = gf(),
h = gf(),
t = gf();
Z(a, p[1], p[0]);
Z(t, q[1], q[0]);
M(a, a, t);
A(b, p[0], p[1]);
A(t, q[0], q[1]);
M(b, b, t);
M(c, p[3], q[3]);
M(c, c, D2);
M(d, p[2], q[2]);
A(d, d, d);
Z(e, b, a);
Z(f, d, c);
A(g, d, c);
A(h, b, a);
M(p[0], e, f);
M(p[1], h, g);
M(p[2], g, f);
M(p[3], e, h);
}
function sel25519(p, q, b) {
const c = ~(b - 1);
let t;
for (let i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]);
p[i] ^= t;
q[i] ^= t;
}
}
module.exports = Ed25519PasswordAuth;

View File

@@ -0,0 +1,55 @@
'use strict';
const PluginAuth = require('./plugin-auth');
const Crypto = require('crypto');
/**
* Standard authentication plugin
*/
class NativePasswordAuth extends PluginAuth {
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
super(resolve, reject, multiAuthResolver);
this.pluginData = pluginData;
this.sequenceNo = packSeq;
this.compressSequenceNo = compressPackSeq;
}
start(out, opts, info) {
//seed is ended with a null byte value.
const data = this.pluginData.slice(0, 20);
let authToken = NativePasswordAuth.encryptPassword(opts.password, data, 'sha1');
out.startPacket(this);
if (authToken.length > 0) {
out.writeBuffer(authToken, 0, authToken.length);
out.flushBuffer(true);
} else {
out.writeEmptyPacket(true);
}
this.emit('send_end');
this.onPacketReceive = this.successSend;
}
static encryptPassword(password, seed, algorithm) {
if (!password) return Buffer.alloc(0);
let hash = Crypto.createHash(algorithm);
let stage1 = hash.update(password, 'utf8').digest();
hash = Crypto.createHash(algorithm);
let stage2 = hash.update(stage1).digest();
hash = Crypto.createHash(algorithm);
hash.update(seed);
hash.update(stage2);
let digest = hash.digest();
let returnBytes = Buffer.allocUnsafe(digest.length);
for (let i = 0; i < digest.length; i++) {
returnBytes[i] = stage1[i] ^ digest[i];
}
return returnBytes;
}
}
module.exports = NativePasswordAuth;

View File

@@ -0,0 +1,58 @@
const PluginAuth = require('./plugin-auth');
/**
* Use PAM authentication
*/
class PamPasswordAuth extends PluginAuth {
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
super(resolve, reject, multiAuthResolver);
this.pluginData = pluginData;
this.sequenceNo = packSeq;
this.counter = 0;
}
start(out, opts, info) {
this.exchange(this.pluginData, out, opts, info);
this.onPacketReceive = this.response;
}
exchange(buffer, out, opts, info) {
//conversation is :
// - first byte is information tell if question is a password (4) or clear text (2).
// - other bytes are the question to user
out.startPacket(this);
let pwd;
if (Array.isArray(opts.password)) {
pwd = opts.password[this.counter];
this.counter++;
} else {
pwd = opts.password;
}
if (pwd) out.writeString(pwd);
out.writeInt8(0);
out.flushBuffer(true);
}
response(packet, out, opts, info) {
const marker = packet.peek();
switch (marker) {
//*********************************************************************************************************
//* OK_Packet and Err_Packet ending packet
//*********************************************************************************************************
case 0x00:
case 0xff:
this.emit('send_end');
return this.successSend(packet, out, opts, info);
default:
let promptData = packet.readBuffer();
this.exchange(promptData, out, opts, info);
this.onPacketReceive = this.response;
}
}
}
module.exports = PamPasswordAuth;

View File

@@ -0,0 +1,19 @@
'use strict';
const Command = require('../../command');
/**
* Base authentication plugin
*/
class PluginAuth extends Command {
constructor(resolve, reject, multiAuthResolver) {
super(resolve, reject);
this.multiAuthResolver = multiAuthResolver;
}
successSend(packet, out, opts, info) {
this.multiAuthResolver(packet, out, opts, info);
}
}
module.exports = PluginAuth;

View File

@@ -0,0 +1,142 @@
const PluginAuth = require('./plugin-auth');
const fs = require('fs');
const crypto = require('crypto');
const Errors = require('../../../misc/errors');
/**
* Use Sha256 authentication
*/
class Sha256PasswordAuth extends PluginAuth {
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
super(resolve, reject, multiAuthResolver);
this.pluginData = pluginData;
this.sequenceNo = packSeq;
this.counter = 0;
this.initialState = true;
}
start(out, opts, info) {
this.exchange(this.pluginData, out, opts, info);
this.onPacketReceive = this.response;
}
exchange(buffer, out, opts, info) {
if (this.initialState) {
if (!opts.password) {
out.startPacket(this);
out.writeEmptyPacket(true);
return;
} else if (opts.ssl) {
// using SSL, so sending password in clear
out.startPacket(this);
if (opts.password) {
out.writeString(opts.password);
}
out.writeInt8(0);
out.flushBuffer(true);
return;
} else {
// retrieve public key from configuration or from server
if (opts.rsaPublicKey) {
try {
let key = opts.rsaPublicKey;
if (!key.includes('-----BEGIN')) {
// rsaPublicKey contain path
key = fs.readFileSync(key, 'utf8');
}
this.publicKey = Sha256PasswordAuth.retreivePublicKey(key);
} catch (err) {
return this.throwError(err, info);
}
} else {
if (!opts.allowPublicKeyRetrieval) {
return this.throwError(
Errors.createError(
'RSA public key is not available client side. Either set option `rsaPublicKey` to indicate' +
' public key path, or allow public key retrieval with option `allowPublicKeyRetrieval`',
true,
info,
'08S01',
Errors.ER_CANNOT_RETRIEVE_RSA_KEY
),
info
);
}
this.initialState = false;
// ask public Key Retrieval
out.startPacket(this);
out.writeInt8(0x01);
out.flushBuffer(true);
return;
}
}
// send Sha256Password Packet
Sha256PasswordAuth.sendSha256PwdPacket(
this,
this.pluginData,
this.publicKey,
opts.password,
out
);
} else {
// has request public key
this.publicKey = Sha256PasswordAuth.retreivePublicKey(buffer.toString('utf8', 1));
Sha256PasswordAuth.sendSha256PwdPacket(
this,
this.pluginData,
this.publicKey,
opts.password,
out
);
}
}
static retreivePublicKey(key) {
return key.replace('(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)', '');
}
static sendSha256PwdPacket(cmd, pluginData, publicKey, password, out) {
const truncatedSeed = pluginData.slice(0, pluginData.length - 1);
out.startPacket(cmd);
const enc = Sha256PasswordAuth.encrypt(truncatedSeed, password, publicKey);
out.writeBuffer(enc, 0, enc.length);
out.flushBuffer(cmd);
}
// encrypt password with public key
static encrypt(seed, password, publicKey) {
const nullFinishedPwd = Buffer.from(password + '\0');
const xorBytes = Buffer.allocUnsafe(nullFinishedPwd.length);
const seedLength = seed.length;
for (let i = 0; i < xorBytes.length; i++) {
xorBytes[i] = nullFinishedPwd[i] ^ seed[i % seedLength];
}
return crypto.publicEncrypt(
{ key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
xorBytes
);
}
response(packet, out, opts, info) {
const marker = packet.peek();
switch (marker) {
//*********************************************************************************************************
//* OK_Packet and Err_Packet ending packet
//*********************************************************************************************************
case 0x00:
case 0xff:
this.emit('send_end');
return this.successSend(packet, out, opts, info);
default:
let promptData = packet.readBufferRemaining();
this.exchange(promptData, out, opts, info);
this.onPacketReceive = this.response;
}
}
}
module.exports = Sha256PasswordAuth;

View File

@@ -0,0 +1,74 @@
'use strict';
const Capabilities = require('../../const/capabilities');
/**
* Initialize client capabilities according to options and server capabilities
*
* @param opts options
* @param info information
*/
module.exports.init = function (opts, info) {
let capabilities =
Capabilities.IGNORE_SPACE |
Capabilities.PROTOCOL_41 |
Capabilities.TRANSACTIONS |
Capabilities.SECURE_CONNECTION |
Capabilities.MULTI_RESULTS |
Capabilities.PS_MULTI_RESULTS |
Capabilities.SESSION_TRACK |
Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA;
if ((info.serverCapabilities & Capabilities.MYSQL) === BigInt(0)) {
capabilities |= Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO;
}
if (info.serverCapabilities & Capabilities.PLUGIN_AUTH) {
capabilities |= Capabilities.PLUGIN_AUTH;
}
if (opts.connectAttributes && info.serverCapabilities & Capabilities.CONNECT_ATTRS) {
capabilities |= Capabilities.CONNECT_ATTRS;
}
if (opts.foundRows) {
capabilities |= Capabilities.FOUND_ROWS;
}
if (opts.permitLocalInfile) {
capabilities |= Capabilities.LOCAL_FILES;
}
if (opts.multipleStatements) {
capabilities |= Capabilities.MULTI_STATEMENTS;
}
info.eofDeprecated = (info.serverCapabilities & Capabilities.DEPRECATE_EOF) > 0;
if (info.eofDeprecated) {
capabilities |= Capabilities.DEPRECATE_EOF;
}
if (opts.database && info.serverCapabilities & Capabilities.CONNECT_WITH_DB) {
capabilities |= Capabilities.CONNECT_WITH_DB;
}
// use compression only if requested by client and supported by server
if (opts.compress) {
if (info.serverCapabilities & Capabilities.COMPRESS) {
capabilities |= Capabilities.COMPRESS;
} else {
opts.compress = false;
}
}
if (opts.bulk) {
if (info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) {
capabilities |= Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS;
}
}
if (opts.permitConnectionWhenExpired) {
capabilities |= Capabilities.CAN_HANDLE_EXPIRED_PASSWORDS;
}
info.clientCapabilities = capabilities;
};

View File

@@ -0,0 +1,126 @@
'use strict';
const Capabilities = require('../../const/capabilities');
const Iconv = require('iconv-lite');
const NativePasswordAuth = require('./auth/native-password-auth');
const Ed25519PasswordAuth = require('./auth/ed25519-password-auth');
const driverVersion = require('../../../package.json').version;
const os = require('os');
/**
* Send Handshake response packet
* see https://mariadb.com/kb/en/library/1-connecting-connecting/#handshake-response-packet
*
* @param cmd current handshake command
* @param out output writer
* @param opts connection options
* @param pluginName plugin name
* @param info connection information
*/
module.exports.send = function send(cmd, out, opts, pluginName, info) {
out.startPacket(cmd);
info.defaultPluginName = pluginName;
const pwd = Array.isArray(opts.password) ? opts.password[0] : opts.password;
let authToken;
let authPlugin;
switch (pluginName) {
case 'client_ed25519':
authToken = Ed25519PasswordAuth.encryptPassword(pwd, info.seed);
authPlugin = 'client_ed25519';
break;
case 'mysql_clear_password':
authToken = Buffer.from(pwd);
authPlugin = 'mysql_clear_password';
break;
default:
authToken = NativePasswordAuth.encryptPassword(pwd, info.seed, 'sha1');
authPlugin = 'mysql_native_password';
break;
}
out.writeInt32(Number(info.clientCapabilities & BigInt(0xffffffff)));
out.writeInt32(1024 * 1024 * 1024); // max packet size
out.writeInt8(opts.collation.index);
for (let i = 0; i < 19; i++) {
out.writeInt8(0);
}
out.writeInt32(Number(info.clientCapabilities >> BigInt(32)));
//null encoded user
out.writeString(opts.user || '');
out.writeInt8(0);
if (info.serverCapabilities & Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA) {
out.writeLengthCoded(authToken.length);
out.writeBuffer(authToken, 0, authToken.length);
} else if (info.serverCapabilities & Capabilities.SECURE_CONNECTION) {
out.writeInt8(authToken.length);
out.writeBuffer(authToken, 0, authToken.length);
} else {
out.writeBuffer(authToken, 0, authToken.length);
out.writeInt8(0);
}
if (info.clientCapabilities & Capabilities.CONNECT_WITH_DB) {
out.writeString(opts.database);
out.writeInt8(0);
info.database = opts.database;
}
if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
out.writeString(authPlugin);
out.writeInt8(0);
}
if (info.clientCapabilities & Capabilities.CONNECT_ATTRS) {
out.writeInt8(0xfc);
let initPos = out.pos; //save position, assuming connection attributes length will be less than 2 bytes length
out.writeInt16(0);
const encoding = opts.collation.charset;
writeParam(out, '_client_name', encoding);
writeParam(out, 'MariaDB connector/Node', encoding);
writeParam(out, '_client_version', encoding);
writeParam(out, driverVersion, encoding);
const address = cmd.getSocket().address().address;
if (address) {
writeParam(out, '_server_host', encoding);
writeParam(out, address, encoding);
}
writeParam(out, '_os', encoding);
writeParam(out, process.platform, encoding);
writeParam(out, '_client_host', encoding);
writeParam(out, os.hostname(), encoding);
writeParam(out, '_node_version', encoding);
writeParam(out, process.versions.node, encoding);
if (opts.connectAttributes !== true) {
let attrNames = Object.keys(opts.connectAttributes);
for (let k = 0; k < attrNames.length; ++k) {
writeParam(out, attrNames[k], encoding);
writeParam(out, opts.connectAttributes[attrNames[k]], encoding);
}
}
//write end size
out.writeInt16AtPos(initPos);
}
out.flushBuffer(true);
};
function writeParam(out, val, encoding) {
let param = Buffer.isEncoding(encoding)
? Buffer.from(val, encoding)
: Iconv.encode(val, encoding);
out.writeLengthCoded(param.length);
out.writeBuffer(param, 0, param.length);
}

287
node_modules/mariadb/lib/cmd/handshake/handshake.js generated vendored Normal file
View File

@@ -0,0 +1,287 @@
'use strict';
const Command = require('../command');
const InitialHandshake = require('./initial-handshake');
const ClientHandshakeResponse = require('./client-handshake-response');
const SslRequest = require('./ssl-request');
const ClientCapabilities = require('./client-capabilities');
const Errors = require('../../misc/errors');
const Capabilities = require('../../const/capabilities');
const process = require('process');
/**
* Handle handshake.
* see https://mariadb.com/kb/en/library/1-connecting-connecting/
*/
class Handshake extends Command {
constructor(resolve, reject, _createSecureContext, _addCommand, getSocket) {
super(resolve, reject);
this._createSecureContext = _createSecureContext;
this._addCommand = _addCommand;
this.getSocket = getSocket;
this.onPacketReceive = this.parseHandshakeInit;
this.plugin = this;
}
ensureOptionCompatibility(opts, info) {
if (
opts.multipleStatements &&
(info.serverCapabilities & Capabilities.MULTI_STATEMENTS) === 0
) {
return this.throwNewError(
"Option `multipleStatements` enable, but server doesn'permits multi-statment",
true,
info,
'08S01',
Errors.ER_CLIENT_OPTION_INCOMPATIBILITY
);
}
if (opts.permitLocalInfile && (info.serverCapabilities & Capabilities.LOCAL_FILES) === 0) {
return this.throwNewError(
"Option `permitLocalInfile` enable, but server doesn'permits using local file",
true,
info,
'08S01',
Errors.ER_CLIENT_OPTION_INCOMPATIBILITY
);
}
}
parseHandshakeInit(packet, out, opts, info) {
if (packet.peek() === 0xff) {
//in case that some host is not permit to connect server
const authErr = packet.readError(info);
authErr.fatal = true;
return this.throwError(authErr, info);
}
let handshake = new InitialHandshake(packet, info);
this.ensureOptionCompatibility(opts, info);
ClientCapabilities.init(opts, info);
if (opts.ssl) {
if (info.serverCapabilities & Capabilities.SSL) {
info.clientCapabilities |= Capabilities.SSL;
SslRequest.send(this, out, info, opts);
this._createSecureContext(
function () {
ClientHandshakeResponse.send(this, out, opts, handshake.pluginName, info);
}.bind(this)
);
} else {
return this.throwNewError(
'Trying to connect with ssl, but ssl not enabled in the server',
true,
info,
'08S01',
Errors.ER_SERVER_SSL_DISABLED
);
}
} else {
ClientHandshakeResponse.send(this, out, opts, handshake.pluginName, info);
}
this.onPacketReceive = this.handshakeResult;
}
/**
* Fast-path handshake results :
* - if plugin was the one expected by server, server will send OK_Packet / ERR_Packet.
* - if not, server send an AuthSwitchRequest packet, indicating the specific PLUGIN to use with this user.
* dispatching to plugin handler then.
*
* @param packet current packet
* @param out output buffer
* @param opts options
* @param info connection info
* @returns {*} return null if authentication succeed, depending on plugin conversation if not finished
*/
handshakeResult(packet, out, opts, info) {
const marker = packet.peek();
switch (marker) {
//*********************************************************************************************************
//* AuthSwitchRequest packet
//*********************************************************************************************************
case 0xfe:
this.plugin.onPacketReceive = null;
this.plugin.emit('send_end');
this.plugin.emit('end');
this.dispatchAuthSwitchRequest(packet, out, opts, info);
return;
//*********************************************************************************************************
//* OK_Packet - authentication succeeded
//*********************************************************************************************************
case 0x00:
packet.skip(1); //skip header
packet.skipLengthCodedNumber(); //skip affected rows
packet.skipLengthCodedNumber(); //skip last insert id
info.status = packet.readUInt16();
this.plugin.emit('send_end');
return this.plugin.successEnd();
//*********************************************************************************************************
//* ERR_Packet
//*********************************************************************************************************
case 0xff:
const authErr = packet.readError(info, this.displaySql());
authErr.fatal = true;
return this.plugin.throwError(authErr, info);
//*********************************************************************************************************
//* unexpected
//*********************************************************************************************************
default:
this.throwNewError(
'Unexpected type of packet during handshake phase : ' + marker,
true,
info,
'42000',
Errors.ER_AUTHENTICATION_BAD_PACKET
);
}
}
/**
* Handle authentication switch request : dispatch to plugin handler.
*
* @param packet packet
* @param out output writer
* @param opts options
* @param info connection information
*/
dispatchAuthSwitchRequest(packet, out, opts, info) {
let pluginName, pluginData;
if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
packet.skip(1); //header
if (packet.remaining()) {
//AuthSwitchRequest packet.
pluginName = packet.readStringNullEnded();
pluginData = packet.readBufferRemaining();
} else {
//OldAuthSwitchRequest
pluginName = 'mysql_old_password';
pluginData = info.seed.slice(0, 8);
}
} else {
pluginName = packet.readStringNullEnded('cesu8');
pluginData = packet.readBufferRemaining();
}
try {
this.plugin = Handshake.pluginHandler(
pluginName,
this.plugin.sequenceNo,
this.plugin.compressSequenceNo,
pluginData,
info,
opts,
out,
this.resolve,
this.reject,
this.handshakeResult.bind(this)
);
} catch (err) {
this.reject(err);
return;
}
if (!this.plugin) {
this.reject(
Errors.createError(
"Client does not support authentication protocol '" +
pluginName +
"' requested by server. ",
true,
info,
'08004',
Errors.ER_AUTHENTICATION_PLUGIN_NOT_SUPPORTED
)
);
} else {
this._addCommand(this.plugin, false);
}
}
static pluginHandler(
pluginName,
packSeq,
compressPackSeq,
pluginData,
info,
opts,
out,
authResolve,
authReject,
multiAuthResolver
) {
let pluginAuth;
switch (pluginName) {
case 'mysql_native_password':
pluginAuth = require('./auth/native-password-auth.js');
break;
case 'mysql_clear_password':
pluginAuth = require('./auth/clear-password-auth.js');
break;
case 'client_ed25519':
pluginAuth = require('./auth/ed25519-password-auth.js');
break;
case 'dialog':
pluginAuth = require('./auth/pam-password-auth.js');
break;
case 'sha256_password':
if (!Handshake.ensureNodeVersion(11, 6, 0)) {
throw Errors.createError(
'sha256_password authentication plugin require node 11.6+',
true,
info,
'08004',
Errors.ER_MINIMUM_NODE_VERSION_REQUIRED
);
}
pluginAuth = require('./auth/sha256-password-auth.js');
break;
case 'caching_sha2_password':
if (!Handshake.ensureNodeVersion(11, 6, 0)) {
throw Errors.createError(
'caching_sha2_password authentication plugin require node 11.6+',
true,
info,
'08004',
Errors.ER_MINIMUM_NODE_VERSION_REQUIRED
);
}
pluginAuth = require('./auth/caching-sha2-password-auth.js');
break;
//TODO "auth_gssapi_client"
default:
return null;
}
return new pluginAuth(
packSeq,
compressPackSeq,
pluginData,
authResolve,
authReject,
multiAuthResolver
);
}
static ensureNodeVersion(major, minor, patch) {
const ver = process.versions.node.split('.');
return (
ver[0] > major ||
(ver[0] === major && ver[1] > minor) ||
(ver[0] === major && ver[1] === minor && ver[2] >= patch)
);
}
}
module.exports = Handshake;

View File

@@ -0,0 +1,74 @@
'use strict';
const Capabilities = require('../../const/capabilities');
const ConnectionInformation = require('../../misc/connection-information');
/**
* Parser server initial handshake.
* see https://mariadb.com/kb/en/library/1-connecting-connecting/#initial-handshake-packet
*/
class InitialHandshake {
constructor(packet, info) {
//protocolVersion
packet.skip(1);
info.serverVersion = {};
info.serverVersion.raw = packet.readStringNullEnded();
info.threadId = packet.readUInt32();
let seed1 = packet.readBuffer(8);
packet.skip(1); //reserved byte
let serverCapabilities = BigInt(packet.readUInt16());
//skip characterSet
packet.skip(1);
info.status = packet.readUInt16();
serverCapabilities += BigInt(packet.readUInt16()) << BigInt(16);
let saltLength = 0;
if (serverCapabilities & Capabilities.PLUGIN_AUTH) {
saltLength = Math.max(12, packet.readUInt8() - 9);
} else {
packet.skip(1);
}
if (serverCapabilities & Capabilities.MYSQL) {
packet.skip(10);
} else {
packet.skip(6);
serverCapabilities += BigInt(packet.readUInt32()) << BigInt(32);
}
if (serverCapabilities & Capabilities.SECURE_CONNECTION) {
let seed2 = packet.readBuffer(saltLength);
info.seed = Buffer.concat([seed1, seed2]);
} else {
info.seed = seed1;
}
packet.skip(1);
info.serverCapabilities = serverCapabilities;
/**
* check for MariaDB 10.x replication hack , remove fake prefix if needed
* MDEV-4088: in 10.0+, the real version string maybe prefixed with "5.5.5-",
* to workaround bugs in Oracle MySQL replication
**/
if (info.serverVersion.raw.startsWith('5.5.5-')) {
info.serverVersion.mariaDb = true;
info.serverVersion.raw = info.serverVersion.raw.substring('5.5.5-'.length);
} else {
//Support for MDEV-7780 faking server version
info.serverVersion.mariaDb =
info.serverVersion.raw.includes('MariaDB') ||
(serverCapabilities & Capabilities.MYSQL) === BigInt(0);
}
if (serverCapabilities & Capabilities.PLUGIN_AUTH) {
this.pluginName = packet.readStringNullEnded();
} else {
this.pluginName = '';
}
ConnectionInformation.parseVersionString(info);
}
}
module.exports = InitialHandshake;

29
node_modules/mariadb/lib/cmd/handshake/ssl-request.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
'use strict';
const Capabilities = require('../../const/capabilities');
/**
* Send SSL Request packet.
* see : https://mariadb.com/kb/en/library/1-connecting-connecting/#sslrequest-packet
*
* @param cmd current command
* @param out output writer
* @param info client information
* @param opts connection options
*/
module.exports.send = function sendSSLRequest(cmd, out, info, opts) {
out.startPacket(cmd);
out.writeInt32(Number(info.clientCapabilities & BigInt(0xffffffff)));
out.writeInt32(1024 * 1024 * 1024); // max packet size
out.writeInt8(opts.collation.index);
for (let i = 0; i < 19; i++) {
out.writeInt8(0);
}
if (info.serverCapabilities & Capabilities.MYSQL) {
out.writeInt32(0);
} else {
out.writeInt32(Number(info.clientCapabilities >> BigInt(32)));
}
out.flushBuffer(true);
};

52
node_modules/mariadb/lib/cmd/ping.js generated vendored Normal file
View File

@@ -0,0 +1,52 @@
'use strict';
const Command = require('./command');
const Errors = require('../misc/errors');
/**
* send a COM_PING: permits sending a packet containing one byte to check that the connection is active.
* see https://mariadb.com/kb/en/library/com_ping/
*/
class Ping extends Command {
constructor(resolve, reject) {
super(resolve, reject);
}
start(out, opts, info) {
out.startPacket(this);
out.writeInt8(0x0e);
out.flushBuffer(true);
this.emit('send_end');
this.onPacketReceive = this.readPingResponsePacket;
}
/**
* Read ping response packet.
* packet can be :
* - an ERR_Packet
* - a OK_Packet
*
* @param packet query response
* @param out output writer
* @param opts connection options
* @param info connection info
*/
readPingResponsePacket(packet, out, opts, info) {
if (packet.peek() !== 0x00) {
return this.throwNewError(
'unexpected packet',
false,
info,
'42000',
Errors.ER_PING_BAD_PACKET
);
}
packet.skip(1); //skip header
packet.skipLengthCodedNumber(); //affected rows
packet.skipLengthCodedNumber(); //insert ids
info.status = packet.readUInt16();
this.successEnd(null);
}
}
module.exports = Ping;

253
node_modules/mariadb/lib/cmd/query.js generated vendored Normal file
View File

@@ -0,0 +1,253 @@
'use strict';
const CommonText = require('./common-text-cmd');
const Errors = require('../misc/errors');
const Parse = require('../misc/parse');
const QUOTE = 0x27;
/**
* Protocol COM_QUERY
* see : https://mariadb.com/kb/en/library/com_query/
*/
class Query extends CommonText {
constructor(resolve, reject, options, connOpts, sql, values) {
super(resolve, reject, options, connOpts, sql, values);
}
/**
* Send COM_QUERY
*
* @param out output writer
* @param opts connection options
* @param info connection information
*/
start(out, opts, info) {
if (!this.initialValues) {
//shortcut if no parameters
out.startPacket(this);
out.writeInt8(0x03);
if (!this.handleTimeout(out, info)) return;
out.writeString(this.sql);
out.flushBuffer(true);
this.emit('send_end');
return (this.onPacketReceive = this.readResponsePacket);
}
if (this.opts.namedPlaceholders) {
try {
const parsed = Parse.splitQueryPlaceholder(
this.sql,
info,
this.initialValues,
this.displaySql.bind(this)
);
this.queryParts = parsed.parts;
this.values = parsed.values;
} catch (err) {
this.emit('send_end');
return this.throwError(err, info);
}
} else {
this.queryParts = Parse.splitQuery(this.sql);
this.values = Array.isArray(this.initialValues) ? this.initialValues : [this.initialValues];
if (!this.validateParameters(info)) return;
}
out.startPacket(this);
out.writeInt8(0x03);
if (!this.handleTimeout(out, info)) return;
out.writeString(this.queryParts[0]);
this.onPacketReceive = this.readResponsePacket;
//********************************************
// send params
//********************************************
const len = this.queryParts.length;
for (let i = 1; i < len; i++) {
const value = this.values[i - 1];
if (
value !== null &&
typeof value === 'object' &&
typeof value.pipe === 'function' &&
typeof value.read === 'function'
) {
this.sending = true;
//********************************************
// param is stream,
// now all params will be written by event
//********************************************
this.registerStreamSendEvent(out, info);
this.currentParam = i;
out.writeInt8(QUOTE); //'
value.on('data', function (chunk) {
out.writeBufferEscape(chunk);
});
value.on(
'end',
function () {
out.writeInt8(QUOTE); //'
out.writeString(this.queryParts[this.currentParam++]);
this.paramWritten();
}.bind(this)
);
return;
} else {
//********************************************
// param isn't stream. directly write in buffer
//********************************************
this.writeParam(out, value, this.opts, info);
out.writeString(this.queryParts[i]);
}
}
out.flushBuffer(true);
this.emit('send_end');
}
/**
* If timeout is set, prepend query with SET STATEMENT max_statement_time=xx FOR, or throw an error
* @param out buffer
* @param info server information
* @returns {boolean} false if an error has been thrown
*/
handleTimeout(out, info) {
if (this.opts.timeout) {
if (info.isMariaDB()) {
if (info.hasMinVersion(10, 1, 2)) {
out.writeString('SET STATEMENT max_statement_time=' + this.opts.timeout / 1000 + ' FOR ');
return true;
} else {
const err = Errors.createError(
'Cannot use timeout for MariaDB server before 10.1.2. timeout value: ' +
this.opts.timeout,
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return false;
}
} else {
//not available for MySQL
// max_execution time exist, but only for select, and as hint
const err = Errors.createError(
'Cannot use timeout for MySQL server. timeout value: ' + this.opts.timeout,
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return false;
}
}
return true;
}
/**
* Validate that parameters exists and are defined.
*
* @param info connection info
* @returns {boolean} return false if any error occur.
*/
validateParameters(info) {
//validate parameter size.
if (this.queryParts.length - 1 > this.values.length) {
this.emit('send_end');
this.throwNewError(
'Parameter at position ' + (this.values.length + 1) + ' is not set\n' + this.displaySql(),
false,
info,
'HY000',
Errors.ER_MISSING_PARAMETER
);
return false;
}
//validate parameter is defined.
for (let i = 0; i < this.queryParts.length - 1; i++) {
if (this.values[i] === undefined) {
this.emit('send_end');
this.throwNewError(
'Parameter at position ' + (i + 1) + ' is undefined\n' + this.displaySql(),
false,
info,
'HY000',
Errors.ER_PARAMETER_UNDEFINED
);
return false;
}
}
return true;
}
/**
* Define params events.
* Each parameter indicate that he is written to socket,
* emitting event so next stream parameter can be written.
*/
registerStreamSendEvent(out, info) {
// note : Implementation use recursive calls, but stack won't never get near v8 max call stack size
//since event launched for stream parameter only
this.paramWritten = function () {
while (true) {
if (this.currentParam === this.queryParts.length) {
//********************************************
// all parameters are written.
// flush packet
//********************************************
out.flushBuffer(true);
this.sending = false;
this.emit('send_end');
return;
} else {
const value = this.values[this.currentParam - 1];
if (value === null) {
out.writeStringAscii('NULL');
out.writeString(this.queryParts[this.currentParam++]);
continue;
}
if (
typeof value === 'object' &&
typeof value.pipe === 'function' &&
typeof value.read === 'function'
) {
//********************************************
// param is stream,
//********************************************
out.writeInt8(QUOTE);
value.once(
'end',
function () {
out.writeInt8(QUOTE);
out.writeString(this.queryParts[this.currentParam++]);
this.paramWritten();
}.bind(this)
);
value.on('data', function (chunk) {
out.writeBufferEscape(chunk);
});
return;
}
//********************************************
// param isn't stream. directly write in buffer
//********************************************
this.writeParam(out, value, this.opts, info);
out.writeString(this.queryParts[this.currentParam++]);
}
}
}.bind(this);
}
}
module.exports = Query;

28
node_modules/mariadb/lib/cmd/quit.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
'use strict';
const Command = require('./command');
/**
* Quit (close connection)
* see https://mariadb.com/kb/en/library/com_quit/
*/
class Quit extends Command {
constructor(resolve, reject) {
super(resolve, reject);
}
start(out, opts, info) {
out.startPacket(this);
out.writeInt8(0x01);
out.flushBuffer(true);
this.emit('send_end');
this.successEnd();
this.onPacketReceive = this.skipResults;
}
skipResults(packet, out, opts, info) {
//deliberately empty, if server send answer
}
}
module.exports = Quit;

54
node_modules/mariadb/lib/cmd/reset.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
'use strict';
const Command = require('./command');
const Errors = require('../misc/errors');
/**
* send a COM_RESET_CONNECTION: permits to reset a connection without re-authentication.
* see https://mariadb.com/kb/en/library/com_reset_connection/
*/
class Reset extends Command {
constructor(resolve, reject) {
super(resolve, reject);
}
start(out, opts, info) {
out.startPacket(this);
out.writeInt8(0x1f);
out.flushBuffer(true);
this.emit('send_end');
this.onPacketReceive = this.readResetResponsePacket;
}
/**
* Read response packet.
* packet can be :
* - an ERR_Packet
* - a OK_Packet
*
* @param packet query response
* @param out output writer
* @param opts connection options
* @param info connection info
*/
readResetResponsePacket(packet, out, opts, info) {
if (packet.peek() !== 0x00) {
return this.throwNewError(
'unexpected packet',
false,
info,
'42000',
Errors.ER_RESET_BAD_PACKET
);
}
packet.skip(1); //skip header
packet.skipLengthCodedNumber(); //affected rows
packet.skipLengthCodedNumber(); //insert ids
info.status = packet.readUInt16();
this.successEnd(null);
}
}
module.exports = Reset;

605
node_modules/mariadb/lib/cmd/resultset.js generated vendored Normal file
View File

@@ -0,0 +1,605 @@
'use strict';
const Command = require('./command');
const ServerStatus = require('../const/server-status');
const ColumnDefinition = require('./column-definition');
const Errors = require('../misc/errors');
const fs = require('fs');
const Parse = require('../misc/parse');
/**
* handle COM_QUERY / COM_STMT_EXECUTE results
* see : https://mariadb.com/kb/en/library/4-server-response-packets/
*/
class ResultSet extends Command {
constructor(resolve, reject) {
super(resolve, reject);
this._responseIndex = 0;
this._rows = [];
}
/**
* Read Query response packet.
* packet can be :
* - a result-set
* - an ERR_Packet
* - a OK_Packet
* - LOCAL_INFILE Packet
*
* @param packet query response
* @param out output writer
* @param opts connection options
* @param info connection info
*/
readResponsePacket(packet, out, opts, info) {
switch (packet.peek()) {
//*********************************************************************************************************
//* OK response
//*********************************************************************************************************
case 0x00:
return this.readOKPacket(packet, out, opts, info);
//*********************************************************************************************************
//* ERROR response
//*********************************************************************************************************
case 0xff:
const err = packet.readError(info, this.displaySql(), this.stack);
//force in transaction status, since query will have created a transaction if autocommit is off
//goal is to avoid unnecessary COMMIT/ROLLBACK.
info.status |= ServerStatus.STATUS_IN_TRANS;
return this.throwError(err, info);
//*********************************************************************************************************
//* LOCAL INFILE response
//*********************************************************************************************************
case 0xfb:
return this.readLocalInfile(packet, out, opts, info);
//*********************************************************************************************************
//* ResultSet
//*********************************************************************************************************
default:
return this.readResultSet(packet);
}
}
/**
* Read result-set packets :
* see https://mariadb.com/kb/en/library/resultset/
*
* @param packet Column count packet
* @returns {ResultSet.readColumn} next packet handler
*/
readResultSet(packet) {
this._columnCount = packet.readUnsignedLength();
this._getValue = this.opts.typeCast ? this.readCastValue : this.readRowData;
this._rows.push([]);
this._columns = [];
this.onPacketReceive = this.readColumn;
}
/**
* Assign global configuration option used by result-set to current query option.
* a little faster than Object.assign() since doest copy all information
*
* @param connOpts connection global configuration
* @param cmdOpts specific command options
*/
configAssign(connOpts, cmdOpts) {
if (!cmdOpts) {
this.opts = connOpts;
return;
}
this.opts = {
timeout: cmdOpts.timeout,
autoJsonMap: connOpts.autoJsonMap,
arrayParenthesis: connOpts.arrayParenthesis,
supportBigInt:
cmdOpts.supportBigInt != undefined ? cmdOpts.supportBigInt : connOpts.supportBigInt,
checkDuplicate:
cmdOpts.checkDuplicate != undefined ? cmdOpts.checkDuplicate : connOpts.checkDuplicate,
typeCast: cmdOpts.typeCast != undefined ? cmdOpts.typeCast : connOpts.typeCast,
rowsAsArray: cmdOpts.rowsAsArray != undefined ? cmdOpts.rowsAsArray : connOpts.rowsAsArray,
nestTables: cmdOpts.nestTables != undefined ? cmdOpts.nestTables : connOpts.nestTables,
dateStrings: cmdOpts.dateStrings != undefined ? cmdOpts.dateStrings : connOpts.dateStrings,
tz: cmdOpts.tz != undefined ? cmdOpts.tz : connOpts.tz,
pipelining: connOpts.pipelining,
localTz: cmdOpts.localTz != undefined ? cmdOpts.localTz : connOpts.localTz,
namedPlaceholders:
cmdOpts.namedPlaceholders != undefined
? cmdOpts.namedPlaceholders
: connOpts.namedPlaceholders,
maxAllowedPacket:
cmdOpts.maxAllowedPacket != undefined
? cmdOpts.maxAllowedPacket
: connOpts.maxAllowedPacket,
supportBigNumbers:
cmdOpts.supportBigNumbers != undefined
? cmdOpts.supportBigNumbers
: connOpts.supportBigNumbers,
permitSetMultiParamEntries:
cmdOpts.permitSetMultiParamEntries != undefined
? cmdOpts.permitSetMultiParamEntries
: connOpts.permitSetMultiParamEntries,
bigNumberStrings:
cmdOpts.bigNumberStrings != undefined ? cmdOpts.bigNumberStrings : connOpts.bigNumberStrings
};
}
/**
* Read OK_Packet.
* see https://mariadb.com/kb/en/library/ok_packet/
*
* @param packet OK_Packet
* @param opts connection options
* @param info connection information
* @param out output writer
* @returns {*} null or {Resultset.readResponsePacket} in case of multi-result-set
*/
readOKPacket(packet, out, opts, info) {
const okPacket = Command.parseOkPacket(packet, out, opts, info);
this._rows.push(okPacket);
if (info.status & ServerStatus.MORE_RESULTS_EXISTS) {
this._responseIndex++;
return (this.onPacketReceive = this.readResponsePacket);
}
this.success(this._responseIndex === 0 ? this._rows[0] : this._rows);
}
/**
* Read COM_STMT_PREPARE response Packet.
* see https://mariadb.com/kb/en/library/com_stmt_prepare/#com_stmt_prepare-response
*
* @param packet COM_STMT_PREPARE_OK packet
* @param opts connection options
* @param info connection information
* @param out output writer
* @returns {*} null or {Resultset.readResponsePacket} in case of multi-result-set
*/
readPrepareResultPacket(packet, out, opts, info) {
switch (packet.peek()) {
//*********************************************************************************************************
//* OK response
//*********************************************************************************************************
case 0x00:
packet.skip(1); //skip header
this.statementId = packet.readInt32();
this.columnNo = packet.readUInt16();
this.parameterNo = packet.readUInt16();
if (this.columnNo > 0) return (this.onPacketReceive = this.skipColumnsPacket);
if (this.parameterNo > 0) return (this.onPacketReceive = this.skipParameterPacket);
return this.success();
//*********************************************************************************************************
//* ERROR response
//*********************************************************************************************************
case 0xff:
const err = packet.readError(info, this.displaySql(), this.stack);
//force in transaction status, since query will have created a transaction if autocommit is off
//goal is to avoid unnecessary COMMIT/ROLLBACK.
info.status |= ServerStatus.STATUS_IN_TRANS;
this.onPacketReceive = this.readResponsePacket;
return this.throwError(err, info);
//*********************************************************************************************************
//* Unexpected response
//*********************************************************************************************************
default:
info.status |= ServerStatus.STATUS_IN_TRANS;
this.onPacketReceive = this.readResponsePacket;
return this.throwError(Errors.ER_UNEXPECTED_PACKET, info);
}
}
skipColumnsPacket(packet, out, opts, info) {
this.columnNo--;
if (this.columnNo === 0) {
if (info.eofDeprecated) {
if (this.parameterNo > 0) return (this.onPacketReceive = this.skipParameterPacket);
this.success();
}
return (this.onPacketReceive = this.skipEofPacket);
}
}
skipEofPacket(packet, out, opts, info) {
if (this.parameterNo > 0) return (this.onPacketReceive = this.skipParameterPacket);
this.success();
}
skipParameterPacket(packet, out, opts, info) {
this.parameterNo--;
if (this.parameterNo === 0) {
if (info.eofDeprecated) return this.success();
return (this.onPacketReceive = this.skipEofPacket);
}
}
success(val) {
this.successEnd(val);
this._columns = null;
this._rows = null;
}
/**
* Read column information metadata
* see https://mariadb.com/kb/en/library/resultset/#column-definition-packet
*
* @param packet column definition packet
* @param out output writer
* @param opts connection options
* @param info connection information
* @returns {*}
*/
readColumn(packet, out, opts, info) {
if (this._columns.length !== this._columnCount) {
this._columns.push(new ColumnDefinition(packet, info));
}
// last column
if (this._columns.length === this._columnCount) {
if (this.opts.rowsAsArray) {
this.parseRow = this.parseRowAsArray;
} else {
this.tableHeader = new Array(this._columnCount);
if (this.opts.nestTables) {
this.parseRow = this.parseRowStd;
if (typeof this.opts.nestTables === 'string') {
for (let i = 0; i < this._columnCount; i++) {
this.tableHeader[i] =
this._columns[i].table() + this.opts.nestTables + this._columns[i].name();
}
this.checkDuplicates();
} else if (this.opts.nestTables === true) {
this.parseRow = this.parseRowNested;
for (let i = 0; i < this._columnCount; i++) {
this.tableHeader[i] = [this._columns[i].table(), this._columns[i].name()];
}
this.checkNestTablesDuplicates();
}
} else {
this.parseRow = this.parseRowStd;
for (let i = 0; i < this._columnCount; i++) {
this.tableHeader[i] = this._columns[i].name();
}
this.checkDuplicates();
}
}
this.emit('fields', this._columns);
return (this.onPacketReceive = info.eofDeprecated
? this.readResultSetRow
: this.readIntermediateEOF);
}
}
checkDuplicates() {
if (this.opts.checkDuplicate) {
for (let i = 0; i < this._columnCount; i++) {
if (this.tableHeader.indexOf(this.tableHeader[i], i + 1) > 0) {
const dupes = this.tableHeader.reduce(
(acc, v, i, arr) =>
arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc,
[]
);
this.throwUnexpectedError(
'Error in results, duplicate field name `' +
dupes[0] +
'`.\n' +
'(see option `checkDuplicate`)',
false,
null,
'42000',
Errors.ER_DUPLICATE_FIELD
);
}
}
}
}
checkNestTablesDuplicates() {
if (this.opts.checkDuplicate) {
for (let i = 0; i < this._columnCount; i++) {
for (let j = 0; j < i; j++) {
if (
this.tableHeader[j][0] === this.tableHeader[i][0] &&
this.tableHeader[j][1] === this.tableHeader[i][1]
) {
this.throwUnexpectedError(
'Error in results, duplicate field name `' +
this.tableHeader[i][0] +
'`.`' +
this.tableHeader[i][1] +
'`\n' +
'(see option `checkDuplicate`)',
false,
null,
'42000',
Errors.ER_DUPLICATE_FIELD
);
}
}
}
}
}
/**
* Read intermediate EOF.
* _only for server before MariaDB 10.2 / MySQL 5.7 that doesn't have CLIENT_DEPRECATE_EOF capability_
* see https://mariadb.com/kb/en/library/eof_packet/
*
* @param packet EOF Packet
* @param out output writer
* @param opts connection options
* @param info connection information
* @returns {*}
*/
readIntermediateEOF(packet, out, opts, info) {
if (packet.peek() !== 0xfe) {
return this.throwNewError(
'Error in protocol, expected EOF packet',
true,
info,
'42000',
Errors.ER_EOF_EXPECTED
);
}
//before MySQL 5.7.5, last EOF doesn't contain the good flag SERVER_MORE_RESULTS_EXISTS
//for OUT parameters. It must be checked here
//(5.7.5 does have the CLIENT_DEPRECATE_EOF capability, so this packet in not even send)
packet.skip(3);
info.status = packet.readUInt16();
this.isOutParameter = info.status & ServerStatus.PS_OUT_PARAMS;
this.onPacketReceive = this.readResultSetRow;
}
handleNewRows(row) {
this._rows[this._responseIndex].push(row);
}
/**
* Check if packet is result-set end = EOF of OK_Packet with EOF header according to CLIENT_DEPRECATE_EOF capability
* or a result-set row
*
* @param packet current packet
* @param out output writer
* @param opts connection options
* @param info connection information
* @returns {*}
*/
readResultSetRow(packet, out, opts, info) {
if (packet.peek() >= 0xfe) {
if (packet.peek() === 0xff) {
const err = packet.readError(info, this.displaySql(), this.stack);
//force in transaction status, since query will have created a transaction if autocommit is off
//goal is to avoid unnecessary COMMIT/ROLLBACK.
info.status |= ServerStatus.STATUS_IN_TRANS;
return this.throwError(err, info);
}
if (
(!info.eofDeprecated && packet.length() < 13) ||
(info.eofDeprecated && packet.length() < 0xffffff)
) {
if (!info.eofDeprecated) {
packet.skip(3);
info.status = packet.readUInt16();
} else {
packet.skip(1); //skip header
packet.skipLengthCodedNumber(); //skip update count
packet.skipLengthCodedNumber(); //skip insert id
info.status = packet.readUInt16();
}
if (opts.metaAsArray) {
//return promise object as array :
// example for SELECT 1 =>
// [
// [ {"1": 1} ], //rows
// [ColumnDefinition] //meta
// ]
if (!this._meta) {
this._meta = new Array(this._responseIndex);
}
this._meta[this._responseIndex] = this._columns;
if (info.status & ServerStatus.MORE_RESULTS_EXISTS || this.isOutParameter) {
this._responseIndex++;
return (this.onPacketReceive = this.readResponsePacket);
}
this.success(
this._responseIndex === 0 ? [this._rows[0], this._meta[0]] : [this._rows, this._meta]
);
} else {
//return promise object as rows that have meta property :
// example for SELECT 1 =>
// [
// {"1": 1},
// meta: [ColumnDefinition]
// ]
this._rows[this._responseIndex].meta = this._columns;
if (info.status & ServerStatus.MORE_RESULTS_EXISTS || this.isOutParameter) {
this._responseIndex++;
return (this.onPacketReceive = this.readResponsePacket);
}
this.success(this._responseIndex === 0 ? this._rows[0] : this._rows);
}
return;
}
}
const row = this.parseRow(this._columns, packet, opts);
this.handleNewRows(row);
}
/**
* Display current SQL with parameters (truncated if too big)
*
* @returns {string}
*/
displaySql() {
if (this.opts && this.initialValues) {
if (this.sql.length > this.opts.debugLen) {
return 'sql: ' + this.sql.substring(0, this.opts.debugLen) + '...';
}
let sqlMsg = 'sql: ' + this.sql + ' - parameters:';
return this.logParameters(sqlMsg, this.initialValues);
}
return 'sql: ' + this.sql + ' - parameters:[]';
}
logParameters(sqlMsg, values) {
if (this.opts.namedPlaceholders) {
sqlMsg += '{';
let first = true;
for (let key in values) {
if (first) {
first = false;
} else {
sqlMsg += ',';
}
sqlMsg += "'" + key + "':";
let param = values[key];
sqlMsg = ResultSet.logParam(sqlMsg, param);
if (sqlMsg.length > this.opts.debugLen) {
sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
break;
}
}
sqlMsg += '}';
} else {
sqlMsg += '[';
if (Array.isArray(values)) {
for (let i = 0; i < values.length; i++) {
if (i !== 0) sqlMsg += ',';
let param = values[i];
sqlMsg = ResultSet.logParam(sqlMsg, param);
if (sqlMsg.length > this.opts.debugLen) {
sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
break;
}
}
} else {
sqlMsg = ResultSet.logParam(sqlMsg, values);
if (sqlMsg.length > this.opts.debugLen) {
sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
}
}
sqlMsg += ']';
}
return sqlMsg;
}
readLocalInfile(packet, out, opts, info) {
packet.skip(1); //skip header
out.startPacket(this);
const fileName = packet.readStringRemaining();
if (!Parse.validateFileName(this.sql, this.initialValues, fileName)) {
out.writeEmptyPacket();
const error = Errors.createError(
"LOCAL INFILE wrong filename. '" +
fileName +
"' doesn't correspond to query " +
this.sql +
'. Query cancelled. Check for malicious server / proxy',
false,
info,
'45034',
Errors.ER_LOCAL_INFILE_WRONG_FILENAME
);
process.nextTick(this.reject, error);
this.reject = null;
this.resolve = null;
return (this.onPacketReceive = this.readResponsePacket);
}
// this.sequenceNo = 2;
// this.compressSequenceNo = 2;
const stream = fs.createReadStream(fileName);
stream.on('error', (err) => {
out.writeEmptyPacket();
const error = Errors.createError(
'LOCAL INFILE command failed: ' + err.message,
false,
info,
'22000',
Errors.ER_LOCAL_INFILE_NOT_READABLE
);
process.nextTick(this.reject, error);
this.reject = null;
this.resolve = null;
});
stream.on('data', (chunk) => {
out.writeBuffer(chunk, 0, chunk.length);
});
stream.on('end', () => {
if (!out.isEmpty()) {
out.flushBuffer(false);
}
out.writeEmptyPacket();
});
this.onPacketReceive = this.readResponsePacket;
}
static logParam(sqlMsg, param) {
if (param === undefined || param === null) {
sqlMsg += param === undefined ? 'undefined' : 'null';
} else {
switch (param.constructor.name) {
case 'Buffer':
sqlMsg += '0x' + param.toString('hex', 0, Math.min(1024, param.length)) + '';
break;
case 'String':
sqlMsg += "'" + param + "'";
break;
case 'Date':
sqlMsg += getStringDate(param);
break;
case 'Object':
sqlMsg += JSON.stringify(param);
break;
default:
sqlMsg += param.toString();
}
}
return sqlMsg;
}
}
function getStringDate(param) {
return (
"'" +
('00' + (param.getMonth() + 1)).slice(-2) +
'/' +
('00' + param.getDate()).slice(-2) +
'/' +
param.getFullYear() +
' ' +
('00' + param.getHours()).slice(-2) +
':' +
('00' + param.getMinutes()).slice(-2) +
':' +
('00' + param.getSeconds()).slice(-2) +
'.' +
('000' + param.getMilliseconds()).slice(-3) +
"'"
);
}
module.exports = ResultSet;

45
node_modules/mariadb/lib/cmd/stream.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
'use strict';
const Query = require('./query');
const { Readable } = require('stream');
/**
* Protocol COM_QUERY with streaming events.
* see : https://mariadb.com/kb/en/library/com_query/
*/
class Stream extends Query {
constructor(cmdOpts, connOpts, sql, values, socket) {
super(
() => {},
() => {},
cmdOpts,
connOpts,
sql,
values
);
this.socket = socket;
this.inStream = new Readable({
objectMode: true,
read: () => {}
});
this.on('fields', function (meta) {
this.inStream.emit('fields', meta);
});
this.on('error', function (err) {
this.inStream.emit('error', err);
});
this.on('end', function (err) {
if (err) this.inStream.emit('error', err);
this.inStream.push(null);
});
}
handleNewRows(row) {
this.inStream.push(row);
}
}
module.exports = Stream;

249
node_modules/mariadb/lib/config/connection-options.js generated vendored Normal file
View File

@@ -0,0 +1,249 @@
'use strict';
const Collations = require('../const/collations.js');
const urlFormat = /mariadb:\/\/(([^/@:]+)?(:([^/]+))?@)?(([^/:]+)(:([0-9]+))?)\/([^?]+)(\?(.*))?$/;
const moment = require('moment-timezone');
const Errors = require('../misc/errors');
/**
* Default option similar to mysql driver.
* known differences
* - no queryFormat option. Permitting client to parse is a security risk. Best is to give SQL + parameters
* Only possible Objects are :
* - Buffer
* - Date
* - Object that implement toSqlString function
* - JSON object
* + rowsAsArray (in mysql2) permit to have rows by index, not by name. Avoiding to parsing metadata string => faster
*/
class ConnectionOptions {
constructor(opts) {
if (typeof opts === 'string') {
opts = ConnectionOptions.parse(opts);
}
if (!opts) opts = {};
this.bigNumberStrings = opts.bigNumberStrings || false;
this.bulk = opts.bulk === undefined || opts.bulk;
if (opts.charset && typeof opts.charset === 'string') {
this.collation = Collations.fromCharset(opts.charset.toLowerCase());
if (this.collation === undefined) {
this.collation = Collations.fromName(opts.charset.toUpperCase());
if (this.collation !== undefined) {
console.log(
"warning: please use option 'collation' " +
"in replacement of 'charset' when using a collation name ('" +
opts.charset +
"')\n" +
"(collation looks like 'UTF8MB4_UNICODE_CI', charset like 'utf8')."
);
}
}
if (this.collation === undefined)
throw new RangeError("Unknown charset '" + opts.charset + "'");
} else if (opts.collation && typeof opts.collation === 'string') {
this.collation = Collations.fromName(opts.collation.toUpperCase());
if (this.collation === undefined)
throw new RangeError("Unknown collation '" + opts.collation + "'");
} else {
this.collation = Collations.fromIndex(opts.charsetNumber) || Collations.fromIndex(224); //UTF8MB4_UNICODE_CI;
}
this.compress = opts.compress || false;
this.logPackets = opts.logPackets || false;
this.connectAttributes = opts.connectAttributes || false;
this.connectTimeout = opts.connectTimeout === undefined ? 10000 : opts.connectTimeout;
this.queryTimeout = opts.queryTimeout === undefined ? 0 : opts.queryTimeout;
this.socketTimeout = opts.socketTimeout === undefined ? 0 : opts.socketTimeout;
this.database = opts.database;
this.checkDuplicate = opts.checkDuplicate === undefined ? true : opts.checkDuplicate;
this.dateStrings = opts.dateStrings || false;
this.debug = opts.debug || false;
this.debugCompress = opts.debugCompress || false;
this.debugLen = opts.debugLen || 256;
this.foundRows = opts.foundRows === undefined || opts.foundRows;
this.host = opts.host || 'localhost';
this.rsaPublicKey = opts.rsaPublicKey;
this.cachingRsaPublicKey = opts.cachingRsaPublicKey;
this.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval || false;
this.initSql = opts.initSql;
this.forceVersionCheck = opts.forceVersionCheck || false;
this.maxAllowedPacket = opts.maxAllowedPacket;
this.metaAsArray = opts.metaAsArray || false;
this.multipleStatements = opts.multipleStatements || false;
this.namedPlaceholders = opts.namedPlaceholders || false;
this.nestTables = opts.nestTables;
this.password = opts.password;
this.autoJsonMap = opts.autoJsonMap === undefined ? true : opts.autoJsonMap;
this.arrayParenthesis = opts.arrayParenthesis || false;
this.keepAliveDelay = opts.keepAliveDelay === undefined ? 0 : opts.keepAliveDelay;
this.permitSetMultiParamEntries = opts.permitSetMultiParamEntries || false;
this.permitConnectionWhenExpired = opts.permitConnectionWhenExpired || false;
this.pipelining = opts.pipelining;
if (opts.pipelining === undefined) {
this.permitLocalInfile = opts.permitLocalInfile || false;
this.pipelining = !this.permitLocalInfile;
} else {
this.pipelining = opts.pipelining;
if (opts.permitLocalInfile === true && this.pipelining) {
throw new Error(
'enabling options `permitLocalInfile` and ' +
'`pipelining` is not possible, options are incompatible.'
);
}
this.permitLocalInfile = this.pipelining ? false : opts.permitLocalInfile || false;
}
this.port = opts.port || 3306;
this.rowsAsArray = opts.rowsAsArray || false;
this.socketPath = opts.socketPath;
this.sessionVariables = opts.sessionVariables;
this.ssl = opts.ssl;
if (opts.ssl) {
if (typeof opts.ssl !== 'boolean' && typeof opts.ssl !== 'string') {
this.ssl.rejectUnauthorized = opts.ssl.rejectUnauthorized !== false;
}
}
this.supportBigNumbers = opts.supportBigNumbers || false;
this.supportBigInt = opts.supportBigInt || false;
this.timezone = opts.timezone || 'local';
this.skipSetTimezone = opts.skipSetTimezone || false;
if (this.timezone && this.timezone !== 'local' && this.timezone !== 'auto') {
let tzName = this.timezone;
if (this.timezone === 'Z') {
tzName = 'Etc/UTC';
} else {
const matched = this.timezone.match(/([+\-\s])(\d\d):?(\d\d)?/);
if (matched) {
const hour = (matched[1] === '-' ? 1 : -1) * Number.parseInt(matched[2], 10);
const minutes = matched.length > 2 && matched[3] ? Number.parseInt(matched[3], 10) : 0;
if (minutes > 0) {
throw new RangeError(
"timezone format incompatible with IANA standard timezone format was '" +
this.timezone +
"'"
);
}
if (hour == 0) {
tzName = 'Etc/UTC';
} else {
tzName = 'Etc/GMT' + (matched[1] === '-' ? '+' : '') + hour;
}
}
}
this.localTz = moment.tz.guess();
if (tzName === this.localTz) {
this.tz = null;
} else {
this.tz = tzName;
if (!moment.tz.zone(tzName)) {
throw Errors.createError(
"Unknown IANA timezone '" + tzName + "'.",
true,
null,
'08S01',
Errors.ER_WRONG_IANA_TIMEZONE
);
}
}
}
this.trace = opts.trace || false;
this.typeCast = opts.typeCast;
if (this.typeCast !== undefined && typeof this.typeCast !== 'function') {
this.typeCast = undefined;
}
this.user = opts.user || process.env.USERNAME;
if (this.maxAllowedPacket && !Number.isInteger(this.maxAllowedPacket)) {
throw new RangeError(
"maxAllowedPacket must be an integer. was '" + this.maxAllowedPacket + "'"
);
}
}
/**
* When parsing from String, correcting type.
*
* @param opts options
* @return {opts}
*/
static parseOptionDataType(opts) {
if (opts.bigNumberStrings) opts.bigNumberStrings = opts.bigNumberStrings == 'true';
if (opts.bulk) opts.bulk = opts.bulk == 'true';
if (opts.rsaPublicKey) opts.rsaPublicKey = opts.rsaPublicKey;
if (opts.cachingRsaPublicKey) opts.cachingRsaPublicKey = opts.cachingRsaPublicKey;
if (opts.logPackets) opts.logPackets = opts.logPackets == 'true';
if (opts.allowPublicKeyRetrieval)
opts.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval == 'true';
if (opts.charsetNumber && !isNaN(Number.parseInt(opts.charsetNumber))) {
opts.charsetNumber = Number.parseInt(opts.charsetNumber);
}
if (opts.compress) opts.compress = opts.compress == 'true';
if (opts.connectAttributes) opts.connectAttributes = JSON.parse(opts.connectAttributes);
if (opts.connectTimeout) opts.connectTimeout = parseInt(opts.connectTimeout);
if (opts.keepAliveDelay) opts.keepAliveDelay = parseInt(opts.keepAliveDelay);
if (opts.socketTimeout) opts.socketTimeout = parseInt(opts.socketTimeout);
if (opts.dateStrings) opts.dateStrings = opts.dateStrings == 'true';
if (opts.debug) opts.debug = opts.debug == 'true';
if (opts.autoJsonMap) opts.autoJsonMap = opts.autoJsonMap == 'true';
if (opts.arrayParenthesis) opts.arrayParenthesis = opts.arrayParenthesis == 'true';
if (opts.skipSetTimezone) opts.skipSetTimezone = opts.skipSetTimezone == 'true';
if (opts.checkDuplicate) opts.checkDuplicate = opts.checkDuplicate == 'true';
if (opts.debugCompress) opts.debugCompress = opts.debugCompress == 'true';
if (opts.debugLen) opts.debugLen = parseInt(opts.debugLen);
if (opts.queryTimeout) opts.queryTimeout = parseInt(opts.queryTimeout);
if (opts.foundRows) opts.foundRows = opts.foundRows == 'true';
if (opts.maxAllowedPacket && !isNaN(Number.parseInt(opts.maxAllowedPacket)))
opts.maxAllowedPacket = parseInt(opts.maxAllowedPacket);
if (opts.metaAsArray) opts.metaAsArray = opts.metaAsArray == 'true';
if (opts.multipleStatements) opts.multipleStatements = opts.multipleStatements == 'true';
if (opts.namedPlaceholders) opts.namedPlaceholders = opts.namedPlaceholders == 'true';
if (opts.nestTables) opts.nestTables = opts.nestTables == 'true';
if (opts.permitSetMultiParamEntries)
opts.permitSetMultiParamEntries = opts.permitSetMultiParamEntries == 'true';
if (opts.pipelining) opts.pipelining = opts.pipelining == 'true';
if (opts.forceVersionCheck) opts.forceVersionCheck = opts.forceVersionCheck == 'true';
if (opts.rowsAsArray) opts.rowsAsArray = opts.rowsAsArray == 'true';
if (opts.supportBigNumbers) opts.supportBigNumbers = opts.supportBigNumbers == 'true';
if (opts.supportBigInt) opts.supportBigInt = opts.supportBigInt == 'true';
if (opts.trace) opts.trace = opts.trace == 'true';
if (opts.ssl && (opts.ssl == 'true' || opts.ssl == 'false')) opts.ssl = opts.ssl == 'true';
return opts;
}
static parse(opts) {
const matchResults = opts.match(urlFormat);
if (!matchResults) {
throw new Error(
"error parsing connection string '" +
opts +
"'. format must be 'mariadb://[<user>[:<password>]@]<host>[:<port>]/[<db>[?<opt1>=<value1>[&<opt2>=<value2>]]]'"
);
}
const options = {
user: matchResults[2] ? decodeURIComponent(matchResults[2]) : undefined,
password: matchResults[4] ? decodeURIComponent(matchResults[4]) : undefined,
host: matchResults[6] ? decodeURIComponent(matchResults[6]) : matchResults[6],
port: matchResults[8] ? parseInt(matchResults[8]) : undefined,
database: matchResults[9] ? decodeURIComponent(matchResults[9]) : matchResults[9]
};
const variousOptsString = matchResults[11];
if (variousOptsString) {
const keyVals = variousOptsString.split('&');
keyVals.forEach(function (keyVal) {
const equalIdx = keyVal.indexOf('=');
if (equalIdx !== 1) {
let val = keyVal.substring(equalIdx + 1);
val = val ? decodeURIComponent(val) : undefined;
options[keyVal.substring(0, equalIdx)] = val;
}
});
}
return this.parseOptionDataType(options);
}
}
module.exports = ConnectionOptions;

View File

@@ -0,0 +1,19 @@
'use strict';
class PoolClusterOptions {
constructor(opts) {
if (opts) {
this.canRetry = opts.canRetry === undefined ? true : opts.canRetry;
this.removeNodeErrorCount = opts.removeNodeErrorCount || 5;
this.restoreNodeTimeout = opts.restoreNodeTimeout || 1000;
this.defaultSelector = opts.defaultSelector || 'RR';
} else {
this.canRetry = true;
this.removeNodeErrorCount = 5;
this.restoreNodeTimeout = 1000;
this.defaultSelector = 'RR';
}
}
}
module.exports = PoolClusterOptions;

47
node_modules/mariadb/lib/config/pool-options.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
'use strict';
let ConnOptions = require('./connection-options');
class PoolOptions {
constructor(opts) {
if (typeof opts === 'string') {
opts = ConnOptions.parse(opts);
//set data type
if (opts.acquireTimeout) opts.acquireTimeout = parseInt(opts.acquireTimeout);
if (opts.connectionLimit) opts.connectionLimit = parseInt(opts.connectionLimit);
if (opts.idleTimeout) opts.idleTimeout = parseInt(opts.idleTimeout);
if (opts.leakDetectionTimeout)
opts.leakDetectionTimeout = parseInt(opts.leakDetectionTimeout);
if (opts.initializationTimeout)
opts.initializationTimeout = parseInt(opts.initializationTimeout);
if (opts.minDelayValidation) opts.minDelayValidation = parseInt(opts.minDelayValidation);
if (opts.minimumIdle) opts.minimumIdle = parseInt(opts.minimumIdle);
if (opts.noControlAfterUse) opts.noControlAfterUse = opts.noControlAfterUse == 'true';
if (opts.resetAfterUse) opts.resetAfterUse = opts.resetAfterUse == 'true';
if (opts.pingTimeout) opts.pingTimeout = parseInt(opts.pingTimeout);
}
this.acquireTimeout = opts.acquireTimeout === undefined ? 10000 : opts.acquireTimeout;
this.connectionLimit = opts.connectionLimit === undefined ? 10 : opts.connectionLimit;
this.idleTimeout = opts.idleTimeout || 1800;
this.leakDetectionTimeout = opts.leakDetectionTimeout || 0;
this.initializationTimeout =
opts.initializationTimeout === undefined ? 30000 : opts.initializationTimeout;
this.minDelayValidation = opts.minDelayValidation === undefined ? 500 : opts.minDelayValidation;
this.minimumIdle =
opts.minimumIdle === undefined
? this.connectionLimit
: Math.min(opts.minimumIdle, this.connectionLimit);
this.noControlAfterUse = opts.noControlAfterUse || false;
this.resetAfterUse = opts.resetAfterUse === undefined ? true : opts.resetAfterUse;
this.pingTimeout = opts.pingTimeout || 250;
this.connOptions = new ConnOptions(opts);
if (this.acquireTimeout > 0 && this.connOptions.connectTimeout > this.acquireTimeout) {
this.connOptions.connectTimeout = this.acquireTimeout;
}
}
}
module.exports = PoolOptions;

158
node_modules/mariadb/lib/connection-callback.js generated vendored Normal file
View File

@@ -0,0 +1,158 @@
'use strict';
const Connection = require('./connection');
const util = require('util');
const Errors = require('./misc/errors');
const { Status } = require('./const/connection_status');
function ConnectionCallback(options) {
Connection.call(this, options);
let connecting = 1;
const connectPromise = this.connect.bind(this);
const changeUserPromise = this.changeUser.bind(this);
const queryPromise = this.query.bind(this);
const endPromise = this.end.bind(this);
const pingPromise = this.ping.bind(this);
const resetPromise = this.reset.bind(this);
const commitPromise = this.commit.bind(this);
const rollbackPromise = this.rollback.bind(this);
const emptySuccess = (rows) => {};
const emptyError = (err) => {};
//*****************************************************************
// internal equivalent with callback of promised functions
//*****************************************************************
const _commitCallback = (callback) => {
commitPromise()
.then(() => {
if (callback) callback(null, null, null);
})
.catch(callback || emptyError);
};
const _rollbackCallback = (callback) => {
rollbackPromise()
.then(() => {
if (callback) callback(null, null, null);
})
.catch(callback || emptyError);
};
const _pingCallback = (timeout, callback) => {
let _timeout, _cb;
if (typeof timeout === 'function') {
_cb = timeout;
_timeout = undefined;
} else {
_timeout = timeout;
_cb = callback;
}
pingPromise(_timeout)
.then(_cb || emptySuccess)
.catch(_cb || emptyError);
};
const _resetCallback = (callback) => {
resetPromise()
.then(callback || emptySuccess)
.catch(callback || emptyError);
};
const _beginTransactionCallback = (callback) => {
queryPromise('START TRANSACTION')
.then(() => {
if (callback) callback(null, null, null);
})
.catch(callback || emptyError);
};
const _endCallback = (callback) => {
endPromise()
.then(callback || emptySuccess)
.catch(callback || emptyError);
};
const _connectCallback = function (callback) {
if (!callback) {
throw new Errors.createError(
'missing callback parameter',
false,
this.info,
'HY000',
Errors.ER_MISSING_PARAMETER
);
}
if (connecting === 1) {
this.on('connect', callback);
} else {
switch (this._status()) {
case Status.CLOSING:
case Status.CLOSED:
callback(
Errors.createError(
'Connection closed',
true,
this.info,
'08S01',
Errors.ER_CONNECTION_ALREADY_CLOSED
)
);
break;
default:
callback();
}
}
};
const _changeUserCallback = (options, callback) => {
let _options, _cb;
if (typeof options === 'function') {
_cb = options;
_options = undefined;
} else {
_options = options;
_cb = callback;
}
changeUserPromise(_options)
.then(() => {
if (_cb) _cb(null, null, null);
})
.catch(_cb || emptyError);
};
//*****************************************************************
// replacing public promise function with callback equivalent
//*****************************************************************
this.commit = _commitCallback;
this.rollback = _rollbackCallback;
this.ping = _pingCallback;
this.reset = _resetCallback;
this.end = _endCallback;
this.connect = _connectCallback;
this.changeUser = _changeUserCallback;
this.query = this._queryCallback;
this.batch = this._batchCallback;
this.beginTransaction = _beginTransactionCallback;
const self = this;
connectPromise()
.then(() => {
connecting = 0;
self.emit('connect');
})
.catch((err) => {
connecting = 0;
self.emit('connect', err);
});
}
util.inherits(ConnectionCallback, Connection);
module.exports = ConnectionCallback;

1435
node_modules/mariadb/lib/connection.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

64
node_modules/mariadb/lib/const/capabilities.js generated vendored Normal file
View File

@@ -0,0 +1,64 @@
/**
* Capabilities list ( with 'CLIENT_' removed)
* see : https://mariadb.com/kb/en/library/1-connecting-connecting/#capabilities
*/
/* mysql/old mariadb server/client */
module.exports.MYSQL = BigInt(1);
/* Found instead of affected rows */
module.exports.FOUND_ROWS = BigInt(2);
/* get all column flags */
module.exports.LONG_FLAG = BigInt(4);
/* one can specify db on connect */
module.exports.CONNECT_WITH_DB = BigInt(8);
/* don't allow database.table.column */
module.exports.NO_SCHEMA = BigInt(1) << BigInt(4);
/* can use compression protocol */
module.exports.COMPRESS = BigInt(1) << BigInt(5);
/* odbc client */
module.exports.ODBC = BigInt(1) << BigInt(6);
/* can use LOAD DATA LOCAL */
module.exports.LOCAL_FILES = BigInt(1) << BigInt(7);
/* ignore spaces before '' */
module.exports.IGNORE_SPACE = BigInt(1) << BigInt(8);
/* new 4.1 protocol */
module.exports.PROTOCOL_41 = BigInt(1) << BigInt(9);
/* this is an interactive client */
module.exports.INTERACTIVE = BigInt(1) << BigInt(10);
/* switch to ssl after handshake */
module.exports.SSL = BigInt(1) << BigInt(11);
/* IGNORE sigpipes */
module.exports.IGNORE_SIGPIPE = BigInt(1) << BigInt(12);
/* client knows about transactions */
module.exports.TRANSACTIONS = BigInt(1) << BigInt(13);
/* old flag for 4.1 protocol */
module.exports.RESERVED = BigInt(1) << BigInt(14);
/* new 4.1 authentication */
module.exports.SECURE_CONNECTION = BigInt(1) << BigInt(15);
/* enable/disable multi-stmt support */
module.exports.MULTI_STATEMENTS = BigInt(1) << BigInt(16);
/* enable/disable multi-results */
module.exports.MULTI_RESULTS = BigInt(1) << BigInt(17);
/* multi-results in ps-protocol */
module.exports.PS_MULTI_RESULTS = BigInt(1) << BigInt(18);
/* client supports plugin authentication */
module.exports.PLUGIN_AUTH = BigInt(1) << BigInt(19);
/* permits connection attributes */
module.exports.CONNECT_ATTRS = BigInt(1) << BigInt(20);
/* Enable authentication response packet to be larger than 255 bytes. */
module.exports.PLUGIN_AUTH_LENENC_CLIENT_DATA = BigInt(1) << BigInt(21);
/* Don't close the connection for a connection with expired password. */
module.exports.CAN_HANDLE_EXPIRED_PASSWORDS = BigInt(1) << BigInt(22);
/* Capable of handling server state change information. Its a hint to the
server to include the state change information in Ok packet. */
module.exports.SESSION_TRACK = BigInt(1) << BigInt(23);
/* Client no longer needs EOF packet */
module.exports.DEPRECATE_EOF = BigInt(1) << BigInt(24);
module.exports.SSL_VERIFY_SERVER_CERT = BigInt(1) << BigInt(30);
/* MariaDB extended capabilities */
/* Permit bulk insert*/
module.exports.MARIADB_CLIENT_STMT_BULK_OPERATIONS = BigInt(1) << BigInt(34);
/* Clients supporting extended metadata */
module.exports.MARIADB_CLIENT_EXTENDED_TYPE_INFO = BigInt(1) << BigInt(35);

473
node_modules/mariadb/lib/const/collations.js generated vendored Normal file
View File

@@ -0,0 +1,473 @@
'use strict';
let charsets = [];
let defaultCharsets = [];
class Collation {
constructor(index, name, charset, maxLength) {
this.index = index;
this.name = name;
this.charset = charset;
}
static fromCharset(charset) {
return defaultCharsets[charset];
}
static fromIndex(index) {
if (index >= charsets.length) return undefined;
return charsets[index];
}
static fromName(name) {
for (let i = 0; i < charsets.length; i++) {
let collation = charsets[i];
if (collation && collation.name === name) {
return collation;
}
}
return undefined;
}
}
// generated with query :
// SELECT CONCAT('charsets[', CAST(co.ID as char), '] = new Collation(', CAST(co.ID as char), ', \'',
// UPPER(co.COLLATION_NAME), '\', \'', co.CHARACTER_SET_NAME, '\', ', CAST(ca.MAXLEN as char), ');\n')
// FROM information_schema.COLLATIONS co
// LEFT OUTER JOIN information_schema.CHARACTER_SETS ca ON ca.character_set_name = co.character_set_name
// ORDER BY co.ID ASC;
//then replace "utf8mb4" by "utf8"
charsets[1] = new Collation(1, 'BIG5_CHINESE_CI', 'big5', 2);
charsets[2] = new Collation(2, 'LATIN2_CZECH_CS', 'latin2', 1);
charsets[3] = new Collation(3, 'DEC8_SWEDISH_CI', 'dec8', 1);
charsets[4] = new Collation(4, 'CP850_GENERAL_CI', 'cp850', 1);
charsets[5] = new Collation(5, 'LATIN1_GERMAN1_CI', 'latin1', 1);
charsets[6] = new Collation(6, 'HP8_ENGLISH_CI', 'hp8', 1);
charsets[7] = new Collation(7, 'KOI8R_GENERAL_CI', 'koi8r', 1);
charsets[8] = new Collation(8, 'LATIN1_SWEDISH_CI', 'latin1', 1);
charsets[9] = new Collation(9, 'LATIN2_GENERAL_CI', 'latin2', 1);
charsets[10] = new Collation(10, 'SWE7_SWEDISH_CI', 'swe7', 1);
charsets[11] = new Collation(11, 'ASCII_GENERAL_CI', 'ascii', 1);
charsets[12] = new Collation(12, 'UJIS_JAPANESE_CI', 'ujis', 3);
charsets[13] = new Collation(13, 'SJIS_JAPANESE_CI', 'sjis', 2);
charsets[14] = new Collation(14, 'CP1251_BULGARIAN_CI', 'cp1251', 1);
charsets[15] = new Collation(15, 'LATIN1_DANISH_CI', 'latin1', 1);
charsets[16] = new Collation(16, 'HEBREW_GENERAL_CI', 'hebrew', 1);
charsets[18] = new Collation(18, 'TIS620_THAI_CI', 'tis620', 1);
charsets[19] = new Collation(19, 'EUCKR_KOREAN_CI', 'euckr', 2);
charsets[20] = new Collation(20, 'LATIN7_ESTONIAN_CS', 'latin7', 1);
charsets[21] = new Collation(21, 'LATIN2_HUNGARIAN_CI', 'latin2', 1);
charsets[22] = new Collation(22, 'KOI8U_GENERAL_CI', 'koi8u', 1);
charsets[23] = new Collation(23, 'CP1251_UKRAINIAN_CI', 'cp1251', 1);
charsets[24] = new Collation(24, 'GB2312_CHINESE_CI', 'gb2312', 2);
charsets[25] = new Collation(25, 'GREEK_GENERAL_CI', 'greek', 1);
charsets[26] = new Collation(26, 'CP1250_GENERAL_CI', 'cp1250', 1);
charsets[27] = new Collation(27, 'LATIN2_CROATIAN_CI', 'latin2', 1);
charsets[28] = new Collation(28, 'GBK_CHINESE_CI', 'gbk', 2);
charsets[29] = new Collation(29, 'CP1257_LITHUANIAN_CI', 'cp1257', 1);
charsets[30] = new Collation(30, 'LATIN5_TURKISH_CI', 'latin5', 1);
charsets[31] = new Collation(31, 'LATIN1_GERMAN2_CI', 'latin1', 1);
charsets[32] = new Collation(32, 'ARMSCII8_GENERAL_CI', 'armscii8', 1);
charsets[33] = new Collation(33, 'UTF8_GENERAL_CI', 'utf8', 3);
charsets[34] = new Collation(34, 'CP1250_CZECH_CS', 'cp1250', 1);
charsets[35] = new Collation(35, 'UCS2_GENERAL_CI', 'ucs2', 2);
charsets[36] = new Collation(36, 'CP866_GENERAL_CI', 'cp866', 1);
charsets[37] = new Collation(37, 'KEYBCS2_GENERAL_CI', 'keybcs2', 1);
charsets[38] = new Collation(38, 'MACCE_GENERAL_CI', 'macce', 1);
charsets[39] = new Collation(39, 'MACROMAN_GENERAL_CI', 'macroman', 1);
charsets[40] = new Collation(40, 'CP852_GENERAL_CI', 'cp852', 1);
charsets[41] = new Collation(41, 'LATIN7_GENERAL_CI', 'latin7', 1);
charsets[42] = new Collation(42, 'LATIN7_GENERAL_CS', 'latin7', 1);
charsets[43] = new Collation(43, 'MACCE_BIN', 'macce', 1);
charsets[44] = new Collation(44, 'CP1250_CROATIAN_CI', 'cp1250', 1);
charsets[45] = new Collation(45, 'UTF8MB4_GENERAL_CI', 'utf8', 4);
charsets[46] = new Collation(46, 'UTF8MB4_BIN', 'utf8', 4);
charsets[47] = new Collation(47, 'LATIN1_BIN', 'latin1', 1);
charsets[48] = new Collation(48, 'LATIN1_GENERAL_CI', 'latin1', 1);
charsets[49] = new Collation(49, 'LATIN1_GENERAL_CS', 'latin1', 1);
charsets[50] = new Collation(50, 'CP1251_BIN', 'cp1251', 1);
charsets[51] = new Collation(51, 'CP1251_GENERAL_CI', 'cp1251', 1);
charsets[52] = new Collation(52, 'CP1251_GENERAL_CS', 'cp1251', 1);
charsets[53] = new Collation(53, 'MACROMAN_BIN', 'macroman', 1);
charsets[54] = new Collation(54, 'UTF16_GENERAL_CI', 'utf16', 4);
charsets[55] = new Collation(55, 'UTF16_BIN', 'utf16', 4);
charsets[56] = new Collation(56, 'UTF16LE_GENERAL_CI', 'utf16le', 4);
charsets[57] = new Collation(57, 'CP1256_GENERAL_CI', 'cp1256', 1);
charsets[58] = new Collation(58, 'CP1257_BIN', 'cp1257', 1);
charsets[59] = new Collation(59, 'CP1257_GENERAL_CI', 'cp1257', 1);
charsets[60] = new Collation(60, 'UTF32_GENERAL_CI', 'utf32', 4);
charsets[61] = new Collation(61, 'UTF32_BIN', 'utf32', 4);
charsets[62] = new Collation(62, 'UTF16LE_BIN', 'utf16le', 4);
charsets[63] = new Collation(63, 'BINARY', 'binary', 1);
charsets[64] = new Collation(64, 'ARMSCII8_BIN', 'armscii8', 1);
charsets[65] = new Collation(65, 'ASCII_BIN', 'ascii', 1);
charsets[66] = new Collation(66, 'CP1250_BIN', 'cp1250', 1);
charsets[67] = new Collation(67, 'CP1256_BIN', 'cp1256', 1);
charsets[68] = new Collation(68, 'CP866_BIN', 'cp866', 1);
charsets[69] = new Collation(69, 'DEC8_BIN', 'dec8', 1);
charsets[70] = new Collation(70, 'GREEK_BIN', 'greek', 1);
charsets[71] = new Collation(71, 'HEBREW_BIN', 'hebrew', 1);
charsets[72] = new Collation(72, 'HP8_BIN', 'hp8', 1);
charsets[73] = new Collation(73, 'KEYBCS2_BIN', 'keybcs2', 1);
charsets[74] = new Collation(74, 'KOI8R_BIN', 'koi8r', 1);
charsets[75] = new Collation(75, 'KOI8U_BIN', 'koi8u', 1);
charsets[76] = new Collation(76, 'UTF8_TOLOWER_CI', 'utf8', 3);
charsets[77] = new Collation(77, 'LATIN2_BIN', 'latin2', 1);
charsets[78] = new Collation(78, 'LATIN5_BIN', 'latin5', 1);
charsets[79] = new Collation(79, 'LATIN7_BIN', 'latin7', 1);
charsets[80] = new Collation(80, 'CP850_BIN', 'cp850', 1);
charsets[81] = new Collation(81, 'CP852_BIN', 'cp852', 1);
charsets[82] = new Collation(82, 'SWE7_BIN', 'swe7', 1);
charsets[83] = new Collation(83, 'UTF8_BIN', 'utf8', 3);
charsets[84] = new Collation(84, 'BIG5_BIN', 'big5', 2);
charsets[85] = new Collation(85, 'EUCKR_BIN', 'euckr', 2);
charsets[86] = new Collation(86, 'GB2312_BIN', 'gb2312', 2);
charsets[87] = new Collation(87, 'GBK_BIN', 'gbk', 2);
charsets[88] = new Collation(88, 'SJIS_BIN', 'sjis', 2);
charsets[89] = new Collation(89, 'TIS620_BIN', 'tis620', 1);
charsets[90] = new Collation(90, 'UCS2_BIN', 'ucs2', 2);
charsets[91] = new Collation(91, 'UJIS_BIN', 'ujis', 3);
charsets[92] = new Collation(92, 'GEOSTD8_GENERAL_CI', 'geostd8', 1);
charsets[93] = new Collation(93, 'GEOSTD8_BIN', 'geostd8', 1);
charsets[94] = new Collation(94, 'LATIN1_SPANISH_CI', 'latin1', 1);
charsets[95] = new Collation(95, 'CP932_JAPANESE_CI', 'cp932', 2);
charsets[96] = new Collation(96, 'CP932_BIN', 'cp932', 2);
charsets[97] = new Collation(97, 'EUCJPMS_JAPANESE_CI', 'eucjpms', 3);
charsets[98] = new Collation(98, 'EUCJPMS_BIN', 'eucjpms', 3);
charsets[99] = new Collation(99, 'CP1250_POLISH_CI', 'cp1250', 1);
charsets[101] = new Collation(101, 'UTF16_UNICODE_CI', 'utf16', 4);
charsets[102] = new Collation(102, 'UTF16_ICELANDIC_CI', 'utf16', 4);
charsets[103] = new Collation(103, 'UTF16_LATVIAN_CI', 'utf16', 4);
charsets[104] = new Collation(104, 'UTF16_ROMANIAN_CI', 'utf16', 4);
charsets[105] = new Collation(105, 'UTF16_SLOVENIAN_CI', 'utf16', 4);
charsets[106] = new Collation(106, 'UTF16_POLISH_CI', 'utf16', 4);
charsets[107] = new Collation(107, 'UTF16_ESTONIAN_CI', 'utf16', 4);
charsets[108] = new Collation(108, 'UTF16_SPANISH_CI', 'utf16', 4);
charsets[109] = new Collation(109, 'UTF16_SWEDISH_CI', 'utf16', 4);
charsets[110] = new Collation(110, 'UTF16_TURKISH_CI', 'utf16', 4);
charsets[111] = new Collation(111, 'UTF16_CZECH_CI', 'utf16', 4);
charsets[112] = new Collation(112, 'UTF16_DANISH_CI', 'utf16', 4);
charsets[113] = new Collation(113, 'UTF16_LITHUANIAN_CI', 'utf16', 4);
charsets[114] = new Collation(114, 'UTF16_SLOVAK_CI', 'utf16', 4);
charsets[115] = new Collation(115, 'UTF16_SPANISH2_CI', 'utf16', 4);
charsets[116] = new Collation(116, 'UTF16_ROMAN_CI', 'utf16', 4);
charsets[117] = new Collation(117, 'UTF16_PERSIAN_CI', 'utf16', 4);
charsets[118] = new Collation(118, 'UTF16_ESPERANTO_CI', 'utf16', 4);
charsets[119] = new Collation(119, 'UTF16_HUNGARIAN_CI', 'utf16', 4);
charsets[120] = new Collation(120, 'UTF16_SINHALA_CI', 'utf16', 4);
charsets[121] = new Collation(121, 'UTF16_GERMAN2_CI', 'utf16', 4);
charsets[122] = new Collation(122, 'UTF16_CROATIAN_MYSQL561_CI', 'utf16', 4);
charsets[123] = new Collation(123, 'UTF16_UNICODE_520_CI', 'utf16', 4);
charsets[124] = new Collation(124, 'UTF16_VIETNAMESE_CI', 'utf16', 4);
charsets[128] = new Collation(128, 'UCS2_UNICODE_CI', 'ucs2', 2);
charsets[129] = new Collation(129, 'UCS2_ICELANDIC_CI', 'ucs2', 2);
charsets[130] = new Collation(130, 'UCS2_LATVIAN_CI', 'ucs2', 2);
charsets[131] = new Collation(131, 'UCS2_ROMANIAN_CI', 'ucs2', 2);
charsets[132] = new Collation(132, 'UCS2_SLOVENIAN_CI', 'ucs2', 2);
charsets[133] = new Collation(133, 'UCS2_POLISH_CI', 'ucs2', 2);
charsets[134] = new Collation(134, 'UCS2_ESTONIAN_CI', 'ucs2', 2);
charsets[135] = new Collation(135, 'UCS2_SPANISH_CI', 'ucs2', 2);
charsets[136] = new Collation(136, 'UCS2_SWEDISH_CI', 'ucs2', 2);
charsets[137] = new Collation(137, 'UCS2_TURKISH_CI', 'ucs2', 2);
charsets[138] = new Collation(138, 'UCS2_CZECH_CI', 'ucs2', 2);
charsets[139] = new Collation(139, 'UCS2_DANISH_CI', 'ucs2', 2);
charsets[140] = new Collation(140, 'UCS2_LITHUANIAN_CI', 'ucs2', 2);
charsets[141] = new Collation(141, 'UCS2_SLOVAK_CI', 'ucs2', 2);
charsets[142] = new Collation(142, 'UCS2_SPANISH2_CI', 'ucs2', 2);
charsets[143] = new Collation(143, 'UCS2_ROMAN_CI', 'ucs2', 2);
charsets[144] = new Collation(144, 'UCS2_PERSIAN_CI', 'ucs2', 2);
charsets[145] = new Collation(145, 'UCS2_ESPERANTO_CI', 'ucs2', 2);
charsets[146] = new Collation(146, 'UCS2_HUNGARIAN_CI', 'ucs2', 2);
charsets[147] = new Collation(147, 'UCS2_SINHALA_CI', 'ucs2', 2);
charsets[148] = new Collation(148, 'UCS2_GERMAN2_CI', 'ucs2', 2);
charsets[149] = new Collation(149, 'UCS2_CROATIAN_MYSQL561_CI', 'ucs2', 2);
charsets[150] = new Collation(150, 'UCS2_UNICODE_520_CI', 'ucs2', 2);
charsets[151] = new Collation(151, 'UCS2_VIETNAMESE_CI', 'ucs2', 2);
charsets[159] = new Collation(159, 'UCS2_GENERAL_MYSQL500_CI', 'ucs2', 2);
charsets[160] = new Collation(160, 'UTF32_UNICODE_CI', 'utf32', 4);
charsets[161] = new Collation(161, 'UTF32_ICELANDIC_CI', 'utf32', 4);
charsets[162] = new Collation(162, 'UTF32_LATVIAN_CI', 'utf32', 4);
charsets[163] = new Collation(163, 'UTF32_ROMANIAN_CI', 'utf32', 4);
charsets[164] = new Collation(164, 'UTF32_SLOVENIAN_CI', 'utf32', 4);
charsets[165] = new Collation(165, 'UTF32_POLISH_CI', 'utf32', 4);
charsets[166] = new Collation(166, 'UTF32_ESTONIAN_CI', 'utf32', 4);
charsets[167] = new Collation(167, 'UTF32_SPANISH_CI', 'utf32', 4);
charsets[168] = new Collation(168, 'UTF32_SWEDISH_CI', 'utf32', 4);
charsets[169] = new Collation(169, 'UTF32_TURKISH_CI', 'utf32', 4);
charsets[170] = new Collation(170, 'UTF32_CZECH_CI', 'utf32', 4);
charsets[171] = new Collation(171, 'UTF32_DANISH_CI', 'utf32', 4);
charsets[172] = new Collation(172, 'UTF32_LITHUANIAN_CI', 'utf32', 4);
charsets[173] = new Collation(173, 'UTF32_SLOVAK_CI', 'utf32', 4);
charsets[174] = new Collation(174, 'UTF32_SPANISH2_CI', 'utf32', 4);
charsets[175] = new Collation(175, 'UTF32_ROMAN_CI', 'utf32', 4);
charsets[176] = new Collation(176, 'UTF32_PERSIAN_CI', 'utf32', 4);
charsets[177] = new Collation(177, 'UTF32_ESPERANTO_CI', 'utf32', 4);
charsets[178] = new Collation(178, 'UTF32_HUNGARIAN_CI', 'utf32', 4);
charsets[179] = new Collation(179, 'UTF32_SINHALA_CI', 'utf32', 4);
charsets[180] = new Collation(180, 'UTF32_GERMAN2_CI', 'utf32', 4);
charsets[181] = new Collation(181, 'UTF32_CROATIAN_MYSQL561_CI', 'utf32', 4);
charsets[182] = new Collation(182, 'UTF32_UNICODE_520_CI', 'utf32', 4);
charsets[183] = new Collation(183, 'UTF32_VIETNAMESE_CI', 'utf32', 4);
charsets[192] = new Collation(192, 'UTF8_UNICODE_CI', 'utf8', 3);
charsets[193] = new Collation(193, 'UTF8_ICELANDIC_CI', 'utf8', 3);
charsets[194] = new Collation(194, 'UTF8_LATVIAN_CI', 'utf8', 3);
charsets[195] = new Collation(195, 'UTF8_ROMANIAN_CI', 'utf8', 3);
charsets[196] = new Collation(196, 'UTF8_SLOVENIAN_CI', 'utf8', 3);
charsets[197] = new Collation(197, 'UTF8_POLISH_CI', 'utf8', 3);
charsets[198] = new Collation(198, 'UTF8_ESTONIAN_CI', 'utf8', 3);
charsets[199] = new Collation(199, 'UTF8_SPANISH_CI', 'utf8', 3);
charsets[200] = new Collation(200, 'UTF8_SWEDISH_CI', 'utf8', 3);
charsets[201] = new Collation(201, 'UTF8_TURKISH_CI', 'utf8', 3);
charsets[202] = new Collation(202, 'UTF8_CZECH_CI', 'utf8', 3);
charsets[203] = new Collation(203, 'UTF8_DANISH_CI', 'utf8', 3);
charsets[204] = new Collation(204, 'UTF8_LITHUANIAN_CI', 'utf8', 3);
charsets[205] = new Collation(205, 'UTF8_SLOVAK_CI', 'utf8', 3);
charsets[206] = new Collation(206, 'UTF8_SPANISH2_CI', 'utf8', 3);
charsets[207] = new Collation(207, 'UTF8_ROMAN_CI', 'utf8', 3);
charsets[208] = new Collation(208, 'UTF8_PERSIAN_CI', 'utf8', 3);
charsets[209] = new Collation(209, 'UTF8_ESPERANTO_CI', 'utf8', 3);
charsets[210] = new Collation(210, 'UTF8_HUNGARIAN_CI', 'utf8', 3);
charsets[211] = new Collation(211, 'UTF8_SINHALA_CI', 'utf8', 3);
charsets[212] = new Collation(212, 'UTF8_GERMAN2_CI', 'utf8', 3);
charsets[213] = new Collation(213, 'UTF8_CROATIAN_MYSQL561_CI', 'utf8', 3);
charsets[214] = new Collation(214, 'UTF8_UNICODE_520_CI', 'utf8', 3);
charsets[215] = new Collation(215, 'UTF8_VIETNAMESE_CI', 'utf8', 3);
charsets[223] = new Collation(223, 'UTF8_GENERAL_MYSQL500_CI', 'utf8', 3);
charsets[224] = new Collation(224, 'UTF8MB4_UNICODE_CI', 'utf8', 4);
charsets[225] = new Collation(225, 'UTF8MB4_ICELANDIC_CI', 'utf8', 4);
charsets[226] = new Collation(226, 'UTF8MB4_LATVIAN_CI', 'utf8', 4);
charsets[227] = new Collation(227, 'UTF8MB4_ROMANIAN_CI', 'utf8', 4);
charsets[228] = new Collation(228, 'UTF8MB4_SLOVENIAN_CI', 'utf8', 4);
charsets[229] = new Collation(229, 'UTF8MB4_POLISH_CI', 'utf8', 4);
charsets[230] = new Collation(230, 'UTF8MB4_ESTONIAN_CI', 'utf8', 4);
charsets[231] = new Collation(231, 'UTF8MB4_SPANISH_CI', 'utf8', 4);
charsets[232] = new Collation(232, 'UTF8MB4_SWEDISH_CI', 'utf8', 4);
charsets[233] = new Collation(233, 'UTF8MB4_TURKISH_CI', 'utf8', 4);
charsets[234] = new Collation(234, 'UTF8MB4_CZECH_CI', 'utf8', 4);
charsets[235] = new Collation(235, 'UTF8MB4_DANISH_CI', 'utf8', 4);
charsets[236] = new Collation(236, 'UTF8MB4_LITHUANIAN_CI', 'utf8', 4);
charsets[237] = new Collation(237, 'UTF8MB4_SLOVAK_CI', 'utf8', 4);
charsets[238] = new Collation(238, 'UTF8MB4_SPANISH2_CI', 'utf8', 4);
charsets[239] = new Collation(239, 'UTF8MB4_ROMAN_CI', 'utf8', 4);
charsets[240] = new Collation(240, 'UTF8MB4_PERSIAN_CI', 'utf8', 4);
charsets[241] = new Collation(241, 'UTF8MB4_ESPERANTO_CI', 'utf8', 4);
charsets[242] = new Collation(242, 'UTF8MB4_HUNGARIAN_CI', 'utf8', 4);
charsets[243] = new Collation(243, 'UTF8MB4_SINHALA_CI', 'utf8', 4);
charsets[244] = new Collation(244, 'UTF8MB4_GERMAN2_CI', 'utf8', 4);
charsets[245] = new Collation(245, 'UTF8MB4_CROATIAN_MYSQL561_CI', 'utf8', 4);
charsets[246] = new Collation(246, 'UTF8MB4_UNICODE_520_CI', 'utf8', 4);
charsets[247] = new Collation(247, 'UTF8MB4_VIETNAMESE_CI', 'utf8', 4);
charsets[248] = new Collation(248, 'GB18030_CHINESE_CI', 'gb18030', 4);
charsets[249] = new Collation(249, 'GB18030_BIN', 'gb18030', 4);
charsets[250] = new Collation(250, 'GB18030_UNICODE_520_CI', 'gb18030', 4);
charsets[255] = new Collation(255, 'UTF8MB4_0900_AI_CI', 'utf8', 4);
charsets[256] = new Collation(256, 'UTF8MB4_DE_PB_0900_AI_CI', 'utf8', 4);
charsets[257] = new Collation(257, 'UTF8MB4_IS_0900_AI_CI', 'utf8', 4);
charsets[258] = new Collation(258, 'UTF8MB4_LV_0900_AI_CI', 'utf8', 4);
charsets[259] = new Collation(259, 'UTF8MB4_RO_0900_AI_CI', 'utf8', 4);
charsets[260] = new Collation(260, 'UTF8MB4_SL_0900_AI_CI', 'utf8', 4);
charsets[261] = new Collation(261, 'UTF8MB4_PL_0900_AI_CI', 'utf8', 4);
charsets[262] = new Collation(262, 'UTF8MB4_ET_0900_AI_CI', 'utf8', 4);
charsets[263] = new Collation(263, 'UTF8MB4_ES_0900_AI_CI', 'utf8', 4);
charsets[264] = new Collation(264, 'UTF8MB4_SV_0900_AI_CI', 'utf8', 4);
charsets[265] = new Collation(265, 'UTF8MB4_TR_0900_AI_CI', 'utf8', 4);
charsets[266] = new Collation(266, 'UTF8MB4_CS_0900_AI_CI', 'utf8', 4);
charsets[267] = new Collation(267, 'UTF8MB4_DA_0900_AI_CI', 'utf8', 4);
charsets[268] = new Collation(268, 'UTF8MB4_LT_0900_AI_CI', 'utf8', 4);
charsets[269] = new Collation(269, 'UTF8MB4_SK_0900_AI_CI', 'utf8', 4);
charsets[270] = new Collation(270, 'UTF8MB4_ES_TRAD_0900_AI_CI', 'utf8', 4);
charsets[271] = new Collation(271, 'UTF8MB4_LA_0900_AI_CI', 'utf8', 4);
charsets[273] = new Collation(273, 'UTF8MB4_EO_0900_AI_CI', 'utf8', 4);
charsets[274] = new Collation(274, 'UTF8MB4_HU_0900_AI_CI', 'utf8', 4);
charsets[275] = new Collation(275, 'UTF8MB4_HR_0900_AI_CI', 'utf8', 4);
charsets[277] = new Collation(277, 'UTF8MB4_VI_0900_AI_CI', 'utf8', 4);
charsets[278] = new Collation(278, 'UTF8MB4_0900_AS_CS', 'utf8', 4);
charsets[279] = new Collation(279, 'UTF8MB4_DE_PB_0900_AS_CS', 'utf8', 4);
charsets[280] = new Collation(280, 'UTF8MB4_IS_0900_AS_CS', 'utf8', 4);
charsets[281] = new Collation(281, 'UTF8MB4_LV_0900_AS_CS', 'utf8', 4);
charsets[282] = new Collation(282, 'UTF8MB4_RO_0900_AS_CS', 'utf8', 4);
charsets[283] = new Collation(283, 'UTF8MB4_SL_0900_AS_CS', 'utf8', 4);
charsets[284] = new Collation(284, 'UTF8MB4_PL_0900_AS_CS', 'utf8', 4);
charsets[285] = new Collation(285, 'UTF8MB4_ET_0900_AS_CS', 'utf8', 4);
charsets[286] = new Collation(286, 'UTF8MB4_ES_0900_AS_CS', 'utf8', 4);
charsets[287] = new Collation(287, 'UTF8MB4_SV_0900_AS_CS', 'utf8', 4);
charsets[288] = new Collation(288, 'UTF8MB4_TR_0900_AS_CS', 'utf8', 4);
charsets[289] = new Collation(289, 'UTF8MB4_CS_0900_AS_CS', 'utf8', 4);
charsets[290] = new Collation(290, 'UTF8MB4_DA_0900_AS_CS', 'utf8', 4);
charsets[291] = new Collation(291, 'UTF8MB4_LT_0900_AS_CS', 'utf8', 4);
charsets[292] = new Collation(292, 'UTF8MB4_SK_0900_AS_CS', 'utf8', 4);
charsets[293] = new Collation(293, 'UTF8MB4_ES_TRAD_0900_AS_CS', 'utf8', 4);
charsets[294] = new Collation(294, 'UTF8MB4_LA_0900_AS_CS', 'utf8', 4);
charsets[296] = new Collation(296, 'UTF8MB4_EO_0900_AS_CS', 'utf8', 4);
charsets[297] = new Collation(297, 'UTF8MB4_HU_0900_AS_CS', 'utf8', 4);
charsets[298] = new Collation(298, 'UTF8MB4_HR_0900_AS_CS', 'utf8', 4);
charsets[300] = new Collation(300, 'UTF8MB4_VI_0900_AS_CS', 'utf8', 4);
charsets[303] = new Collation(303, 'UTF8MB4_JA_0900_AS_CS', 'utf8', 4);
charsets[304] = new Collation(304, 'UTF8MB4_JA_0900_AS_CS_KS', 'utf8', 4);
charsets[305] = new Collation(305, 'UTF8MB4_0900_AS_CI', 'utf8', 4);
charsets[306] = new Collation(306, 'UTF8MB4_RU_0900_AI_CI', 'utf8', 4);
charsets[307] = new Collation(307, 'UTF8MB4_RU_0900_AS_CS', 'utf8', 4);
charsets[308] = new Collation(308, 'UTF8MB4_ZH_0900_AS_CS', 'utf8', 4);
charsets[309] = new Collation(309, 'UTF8MB4_0900_BIN', 'utf8', 4);
charsets[576] = new Collation(576, 'UTF8_CROATIAN_CI', 'utf8', 3);
charsets[577] = new Collation(577, 'UTF8_MYANMAR_CI', 'utf8', 3);
charsets[578] = new Collation(578, 'UTF8_THAI_520_W2', 'utf8', 3);
charsets[608] = new Collation(608, 'UTF8MB4_CROATIAN_CI', 'utf8', 4);
charsets[609] = new Collation(609, 'UTF8MB4_MYANMAR_CI', 'utf8', 4);
charsets[610] = new Collation(610, 'UTF8MB4_THAI_520_W2', 'utf8', 4);
charsets[640] = new Collation(640, 'UCS2_CROATIAN_CI', 'ucs2', 2);
charsets[641] = new Collation(641, 'UCS2_MYANMAR_CI', 'ucs2', 2);
charsets[642] = new Collation(642, 'UCS2_THAI_520_W2', 'ucs2', 2);
charsets[672] = new Collation(672, 'UTF16_CROATIAN_CI', 'utf16', 4);
charsets[673] = new Collation(673, 'UTF16_MYANMAR_CI', 'utf16', 4);
charsets[674] = new Collation(674, 'UTF16_THAI_520_W2', 'utf16', 4);
charsets[736] = new Collation(736, 'UTF32_CROATIAN_CI', 'utf32', 4);
charsets[737] = new Collation(737, 'UTF32_MYANMAR_CI', 'utf32', 4);
charsets[738] = new Collation(738, 'UTF32_THAI_520_W2', 'utf32', 4);
charsets[1025] = new Collation(1025, 'BIG5_CHINESE_NOPAD_CI', 'big5', 2);
charsets[1027] = new Collation(1027, 'DEC8_SWEDISH_NOPAD_CI', 'dec8', 1);
charsets[1028] = new Collation(1028, 'CP850_GENERAL_NOPAD_CI', 'cp850', 1);
charsets[1030] = new Collation(1030, 'HP8_ENGLISH_NOPAD_CI', 'hp8', 1);
charsets[1031] = new Collation(1031, 'KOI8R_GENERAL_NOPAD_CI', 'koi8r', 1);
charsets[1032] = new Collation(1032, 'LATIN1_SWEDISH_NOPAD_CI', 'latin1', 1);
charsets[1033] = new Collation(1033, 'LATIN2_GENERAL_NOPAD_CI', 'latin2', 1);
charsets[1034] = new Collation(1034, 'SWE7_SWEDISH_NOPAD_CI', 'swe7', 1);
charsets[1035] = new Collation(1035, 'ASCII_GENERAL_NOPAD_CI', 'ascii', 1);
charsets[1036] = new Collation(1036, 'UJIS_JAPANESE_NOPAD_CI', 'ujis', 3);
charsets[1037] = new Collation(1037, 'SJIS_JAPANESE_NOPAD_CI', 'sjis', 2);
charsets[1040] = new Collation(1040, 'HEBREW_GENERAL_NOPAD_CI', 'hebrew', 1);
charsets[1042] = new Collation(1042, 'TIS620_THAI_NOPAD_CI', 'tis620', 1);
charsets[1043] = new Collation(1043, 'EUCKR_KOREAN_NOPAD_CI', 'euckr', 2);
charsets[1046] = new Collation(1046, 'KOI8U_GENERAL_NOPAD_CI', 'koi8u', 1);
charsets[1048] = new Collation(1048, 'GB2312_CHINESE_NOPAD_CI', 'gb2312', 2);
charsets[1049] = new Collation(1049, 'GREEK_GENERAL_NOPAD_CI', 'greek', 1);
charsets[1050] = new Collation(1050, 'CP1250_GENERAL_NOPAD_CI', 'cp1250', 1);
charsets[1052] = new Collation(1052, 'GBK_CHINESE_NOPAD_CI', 'gbk', 2);
charsets[1054] = new Collation(1054, 'LATIN5_TURKISH_NOPAD_CI', 'latin5', 1);
charsets[1056] = new Collation(1056, 'ARMSCII8_GENERAL_NOPAD_CI', 'armscii8', 1);
charsets[1057] = new Collation(1057, 'UTF8_GENERAL_NOPAD_CI', 'utf8', 3);
charsets[1059] = new Collation(1059, 'UCS2_GENERAL_NOPAD_CI', 'ucs2', 2);
charsets[1060] = new Collation(1060, 'CP866_GENERAL_NOPAD_CI', 'cp866', 1);
charsets[1061] = new Collation(1061, 'KEYBCS2_GENERAL_NOPAD_CI', 'keybcs2', 1);
charsets[1062] = new Collation(1062, 'MACCE_GENERAL_NOPAD_CI', 'macce', 1);
charsets[1063] = new Collation(1063, 'MACROMAN_GENERAL_NOPAD_CI', 'macroman', 1);
charsets[1064] = new Collation(1064, 'CP852_GENERAL_NOPAD_CI', 'cp852', 1);
charsets[1065] = new Collation(1065, 'LATIN7_GENERAL_NOPAD_CI', 'latin7', 1);
charsets[1067] = new Collation(1067, 'MACCE_NOPAD_BIN', 'macce', 1);
charsets[1069] = new Collation(1069, 'UTF8MB4_GENERAL_NOPAD_CI', 'utf8', 4);
charsets[1070] = new Collation(1070, 'UTF8MB4_NOPAD_BIN', 'utf8', 4);
charsets[1071] = new Collation(1071, 'LATIN1_NOPAD_BIN', 'latin1', 1);
charsets[1074] = new Collation(1074, 'CP1251_NOPAD_BIN', 'cp1251', 1);
charsets[1075] = new Collation(1075, 'CP1251_GENERAL_NOPAD_CI', 'cp1251', 1);
charsets[1077] = new Collation(1077, 'MACROMAN_NOPAD_BIN', 'macroman', 1);
charsets[1078] = new Collation(1078, 'UTF16_GENERAL_NOPAD_CI', 'utf16', 4);
charsets[1079] = new Collation(1079, 'UTF16_NOPAD_BIN', 'utf16', 4);
charsets[1080] = new Collation(1080, 'UTF16LE_GENERAL_NOPAD_CI', 'utf16le', 4);
charsets[1081] = new Collation(1081, 'CP1256_GENERAL_NOPAD_CI', 'cp1256', 1);
charsets[1082] = new Collation(1082, 'CP1257_NOPAD_BIN', 'cp1257', 1);
charsets[1083] = new Collation(1083, 'CP1257_GENERAL_NOPAD_CI', 'cp1257', 1);
charsets[1084] = new Collation(1084, 'UTF32_GENERAL_NOPAD_CI', 'utf32', 4);
charsets[1085] = new Collation(1085, 'UTF32_NOPAD_BIN', 'utf32', 4);
charsets[1086] = new Collation(1086, 'UTF16LE_NOPAD_BIN', 'utf16le', 4);
charsets[1088] = new Collation(1088, 'ARMSCII8_NOPAD_BIN', 'armscii8', 1);
charsets[1089] = new Collation(1089, 'ASCII_NOPAD_BIN', 'ascii', 1);
charsets[1090] = new Collation(1090, 'CP1250_NOPAD_BIN', 'cp1250', 1);
charsets[1091] = new Collation(1091, 'CP1256_NOPAD_BIN', 'cp1256', 1);
charsets[1092] = new Collation(1092, 'CP866_NOPAD_BIN', 'cp866', 1);
charsets[1093] = new Collation(1093, 'DEC8_NOPAD_BIN', 'dec8', 1);
charsets[1094] = new Collation(1094, 'GREEK_NOPAD_BIN', 'greek', 1);
charsets[1095] = new Collation(1095, 'HEBREW_NOPAD_BIN', 'hebrew', 1);
charsets[1096] = new Collation(1096, 'HP8_NOPAD_BIN', 'hp8', 1);
charsets[1097] = new Collation(1097, 'KEYBCS2_NOPAD_BIN', 'keybcs2', 1);
charsets[1098] = new Collation(1098, 'KOI8R_NOPAD_BIN', 'koi8r', 1);
charsets[1099] = new Collation(1099, 'KOI8U_NOPAD_BIN', 'koi8u', 1);
charsets[1101] = new Collation(1101, 'LATIN2_NOPAD_BIN', 'latin2', 1);
charsets[1102] = new Collation(1102, 'LATIN5_NOPAD_BIN', 'latin5', 1);
charsets[1103] = new Collation(1103, 'LATIN7_NOPAD_BIN', 'latin7', 1);
charsets[1104] = new Collation(1104, 'CP850_NOPAD_BIN', 'cp850', 1);
charsets[1105] = new Collation(1105, 'CP852_NOPAD_BIN', 'cp852', 1);
charsets[1106] = new Collation(1106, 'SWE7_NOPAD_BIN', 'swe7', 1);
charsets[1107] = new Collation(1107, 'UTF8_NOPAD_BIN', 'utf8', 3);
charsets[1108] = new Collation(1108, 'BIG5_NOPAD_BIN', 'big5', 2);
charsets[1109] = new Collation(1109, 'EUCKR_NOPAD_BIN', 'euckr', 2);
charsets[1110] = new Collation(1110, 'GB2312_NOPAD_BIN', 'gb2312', 2);
charsets[1111] = new Collation(1111, 'GBK_NOPAD_BIN', 'gbk', 2);
charsets[1112] = new Collation(1112, 'SJIS_NOPAD_BIN', 'sjis', 2);
charsets[1113] = new Collation(1113, 'TIS620_NOPAD_BIN', 'tis620', 1);
charsets[1114] = new Collation(1114, 'UCS2_NOPAD_BIN', 'ucs2', 2);
charsets[1115] = new Collation(1115, 'UJIS_NOPAD_BIN', 'ujis', 3);
charsets[1116] = new Collation(1116, 'GEOSTD8_GENERAL_NOPAD_CI', 'geostd8', 1);
charsets[1117] = new Collation(1117, 'GEOSTD8_NOPAD_BIN', 'geostd8', 1);
charsets[1119] = new Collation(1119, 'CP932_JAPANESE_NOPAD_CI', 'cp932', 2);
charsets[1120] = new Collation(1120, 'CP932_NOPAD_BIN', 'cp932', 2);
charsets[1121] = new Collation(1121, 'EUCJPMS_JAPANESE_NOPAD_CI', 'eucjpms', 3);
charsets[1122] = new Collation(1122, 'EUCJPMS_NOPAD_BIN', 'eucjpms', 3);
charsets[1125] = new Collation(1125, 'UTF16_UNICODE_NOPAD_CI', 'utf16', 4);
charsets[1147] = new Collation(1147, 'UTF16_UNICODE_520_NOPAD_CI', 'utf16', 4);
charsets[1152] = new Collation(1152, 'UCS2_UNICODE_NOPAD_CI', 'ucs2', 2);
charsets[1174] = new Collation(1174, 'UCS2_UNICODE_520_NOPAD_CI', 'ucs2', 2);
charsets[1184] = new Collation(1184, 'UTF32_UNICODE_NOPAD_CI', 'utf32', 4);
charsets[1206] = new Collation(1206, 'UTF32_UNICODE_520_NOPAD_CI', 'utf32', 4);
charsets[1216] = new Collation(1216, 'UTF8_UNICODE_NOPAD_CI', 'utf8', 3);
charsets[1238] = new Collation(1238, 'UTF8_UNICODE_520_NOPAD_CI', 'utf8', 3);
charsets[1248] = new Collation(1248, 'UTF8MB4_UNICODE_NOPAD_CI', 'utf8', 4);
charsets[1270] = new Collation(1270, 'UTF8MB4_UNICODE_520_NOPAD_CI', 'utf8', 4);
for (let i = 0; i < charsets.length; i++) {
let collation = charsets[i];
if (collation) {
Collation.prototype[collation.name] = collation;
}
}
/**
* Map charset to default collation
*
* created with query:
* SELECT CONCAT(' defaultCharsets[\'', co.character_set_name , '\'] = charsets[', CAST(co.ID as char), '];')
* FROM information_schema.COLLATIONS co WHERE co.IS_DEFAULT = 'Yes' ORDER BY co.ID ASC;
*/
defaultCharsets['big5'] = charsets[1];
defaultCharsets['dec8'] = charsets[3];
defaultCharsets['cp850'] = charsets[4];
defaultCharsets['hp8'] = charsets[6];
defaultCharsets['koi8r'] = charsets[7];
defaultCharsets['latin1'] = charsets[8];
defaultCharsets['latin2'] = charsets[9];
defaultCharsets['swe7'] = charsets[10];
defaultCharsets['ascii'] = charsets[11];
defaultCharsets['ujis'] = charsets[12];
defaultCharsets['sjis'] = charsets[13];
defaultCharsets['hebrew'] = charsets[16];
defaultCharsets['tis620'] = charsets[18];
defaultCharsets['euckr'] = charsets[19];
defaultCharsets['koi8u'] = charsets[22];
defaultCharsets['gb2312'] = charsets[24];
defaultCharsets['greek'] = charsets[25];
defaultCharsets['cp1250'] = charsets[26];
defaultCharsets['gbk'] = charsets[28];
defaultCharsets['latin5'] = charsets[30];
defaultCharsets['armscii8'] = charsets[32];
defaultCharsets['utf8'] = charsets[33];
defaultCharsets['ucs2'] = charsets[35];
defaultCharsets['cp866'] = charsets[36];
defaultCharsets['keybcs2'] = charsets[37];
defaultCharsets['macce'] = charsets[38];
defaultCharsets['macroman'] = charsets[39];
defaultCharsets['cp852'] = charsets[40];
defaultCharsets['latin7'] = charsets[41];
defaultCharsets['utf8mb4'] = charsets[45];
defaultCharsets['cp1251'] = charsets[51];
defaultCharsets['utf16'] = charsets[54];
defaultCharsets['utf16le'] = charsets[56];
defaultCharsets['cp1256'] = charsets[57];
defaultCharsets['cp1257'] = charsets[59];
defaultCharsets['utf32'] = charsets[60];
defaultCharsets['binary'] = charsets[63];
defaultCharsets['geostd8'] = charsets[92];
defaultCharsets['cp932'] = charsets[95];
defaultCharsets['eucjpms'] = charsets[97];
defaultCharsets['gb18030'] = charsets[248];
module.exports = Collation;

13
node_modules/mariadb/lib/const/connection_status.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
'use strict';
const Status = {
NOT_CONNECTED: 1,
CONNECTING: 2,
AUTHENTICATING: 3,
INIT_CMD: 4,
CONNECTED: 5,
CLOSING: 6,
CLOSED: 7
};
module.exports.Status = Status;

1282
node_modules/mariadb/lib/const/error-code.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

35
node_modules/mariadb/lib/const/field-detail.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
/**
* Column definition packet "Field detail" flag value
* see : https://mariadb.com/kb/en/library/resultset/#field-detail-flag
*/
// field cannot be null
module.exports.NOT_NULL = 1;
// field is a primary key
module.exports.PRIMARY_KEY = 2;
//field is unique
module.exports.UNIQUE_KEY = 4;
//field is in a multiple key
module.exports.MULTIPLE_KEY = 8;
//is this field a Blob
module.exports.BLOB = 1 << 4;
// is this field unsigned
module.exports.UNSIGNED = 1 << 5;
//is this field a zerofill
module.exports.ZEROFILL_FLAG = 1 << 6;
//whether this field has a binary collation
module.exports.BINARY_COLLATION = 1 << 7;
//Field is an enumeration
module.exports.ENUM = 1 << 8;
//field auto-increment
module.exports.AUTO_INCREMENT = 1 << 9;
//field is a timestamp value
module.exports.TIMESTAMP = 1 << 10;
//field is a SET
module.exports.SET = 1 << 11;
//field doesn't have default value
module.exports.NO_DEFAULT_VALUE_FLAG = 1 << 12;
//field is set to NOW on UPDATE
module.exports.ON_UPDATE_NOW_FLAG = 1 << 13;
//field is num
module.exports.NUM_FLAG = 1 << 14;

71
node_modules/mariadb/lib/const/field-type.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
/**
* Field types
* see https://mariadb.com/kb/en/library/resultset/#field-types
*/
module.exports.DECIMAL = 0;
module.exports.TINY = 1;
module.exports.SHORT = 2;
module.exports.LONG = 3;
module.exports.FLOAT = 4;
module.exports.DOUBLE = 5;
module.exports.NULL = 6;
module.exports.TIMESTAMP = 7;
module.exports.LONGLONG = 8;
module.exports.INT24 = 9;
module.exports.DATE = 10;
module.exports.TIME = 11;
module.exports.DATETIME = 12;
module.exports.YEAR = 13;
module.exports.NEWDATE = 14;
module.exports.VARCHAR = 15;
module.exports.BIT = 16;
module.exports.TIMESTAMP2 = 17;
module.exports.DATETIME2 = 18;
module.exports.TIME2 = 19;
module.exports.JSON = 245; //only for MySQL
module.exports.NEWDECIMAL = 246;
module.exports.ENUM = 247;
module.exports.SET = 248;
module.exports.TINY_BLOB = 249;
module.exports.MEDIUM_BLOB = 250;
module.exports.LONG_BLOB = 251;
module.exports.BLOB = 252;
module.exports.VAR_STRING = 253;
module.exports.STRING = 254;
module.exports.GEOMETRY = 255;
const typeNames = [];
typeNames[0] = 'DECIMAL';
typeNames[1] = 'TINY';
typeNames[2] = 'SHORT';
typeNames[3] = 'LONG';
typeNames[4] = 'FLOAT';
typeNames[5] = 'DOUBLE';
typeNames[6] = 'NULL';
typeNames[7] = 'TIMESTAMP';
typeNames[8] = 'LONGLONG';
typeNames[9] = 'INT24';
typeNames[10] = 'DATE';
typeNames[11] = 'TIME';
typeNames[12] = 'DATETIME';
typeNames[13] = 'YEAR';
typeNames[14] = 'NEWDATE';
typeNames[15] = 'VARCHAR';
typeNames[16] = 'BIT';
typeNames[17] = 'TIMESTAMP2';
typeNames[18] = 'DATETIME2';
typeNames[19] = 'TIME2';
typeNames[245] = 'JSON';
typeNames[246] = 'NEWDECIMAL';
typeNames[247] = 'ENUM';
typeNames[248] = 'SET';
typeNames[249] = 'TINY_BLOB';
typeNames[250] = 'MEDIUM_BLOB';
typeNames[251] = 'LONG_BLOB';
typeNames[252] = 'BLOB';
typeNames[253] = 'VAR_STRING';
typeNames[254] = 'STRING';
typeNames[255] = 'GEOMETRY';
module.exports.TYPES = typeNames;

30
node_modules/mariadb/lib/const/server-status.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
/**
* possible server status flag value
* see https://mariadb.com/kb/en/library/ok_packet/#server-status-flag
* @type {number}
*/
//A transaction is currently active
module.exports.STATUS_IN_TRANS = 1;
//Autocommit mode is set
module.exports.STATUS_AUTOCOMMIT = 2;
//more results exists (more packet follow)
module.exports.MORE_RESULTS_EXISTS = 8;
module.exports.QUERY_NO_GOOD_INDEX_USED = 16;
module.exports.QUERY_NO_INDEX_USED = 32;
//when using COM_STMT_FETCH, indicate that current cursor still has result (deprecated)
module.exports.STATUS_CURSOR_EXISTS = 64;
//when using COM_STMT_FETCH, indicate that current cursor has finished to send results (deprecated)
module.exports.STATUS_LAST_ROW_SENT = 128;
//database has been dropped
module.exports.STATUS_DB_DROPPED = 1 << 8;
//current escape mode is "no backslash escape"
module.exports.STATUS_NO_BACKSLASH_ESCAPES = 1 << 9;
//A DDL change did have an impact on an existing PREPARE (an automatic reprepare has been executed)
module.exports.STATUS_METADATA_CHANGED = 1 << 10;
module.exports.QUERY_WAS_SLOW = 1 << 11;
//this result-set contain stored procedure output parameter
module.exports.PS_OUT_PARAMS = 1 << 12;
//current transaction is a read-only transaction
module.exports.STATUS_IN_TRANS_READONLY = 1 << 13;
//session state change. see Session change type for more information
module.exports.SESSION_STATE_CHANGED = 1 << 14;

12
node_modules/mariadb/lib/const/state-change.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
/**
* Session change type.
* see : https://mariadb.com/kb/en/library/ok_packet/#session-change-type
* @type {number}
*/
module.exports.SESSION_TRACK_SYSTEM_VARIABLES = 0;
module.exports.SESSION_TRACK_SCHEMA = 1;
module.exports.SESSION_TRACK_STATE_CHANGE = 2;
module.exports.SESSION_TRACK_GTIDS = 3;
module.exports.SESSION_TRACK_TRANSACTION_CHARACTERISTICS = 4;
module.exports.SESSION_TRACK_TRANSACTION_STATE = 5;

81
node_modules/mariadb/lib/filtered-pool-cluster.js generated vendored Normal file
View File

@@ -0,0 +1,81 @@
/**
* Similar to pool cluster with pre-set pattern and selector.
* Additional method query
*
* @param poolCluster cluster
* @param patternArg pre-set pattern
* @param selectorArg pre-set selector
* @constructor
*/
function FilteredPoolCluster(poolCluster, patternArg, selectorArg) {
const cluster = poolCluster;
const pattern = patternArg;
const selector = selectorArg;
/**
* Get a connection according to previously indicated pattern and selector.
*
* @return {Promise}
*/
this.getConnection = () => {
return cluster.getConnection(pattern, selector);
};
/**
* Execute a query on one connection from available pools matching pattern
* in cluster.
*
* @param sql sql command
* @param value parameter value of sql command (not mandatory)
* @return {Promise}
*/
this.query = function (sql, value) {
return cluster
.getConnection(pattern, selector)
.then((conn) => {
return conn
.query(sql, value)
.then((res) => {
conn.end();
return res;
})
.catch((err) => {
conn.end();
return Promise.reject(err);
});
})
.catch((err) => {
return Promise.reject(err);
});
};
/**
* Execute a batch on one connection from available pools matching pattern
* in cluster.
*
* @param sql sql command
* @param value parameter value of sql command
* @return {Promise}
*/
this.batch = function (sql, value) {
return cluster
.getConnection(pattern, selector)
.then((conn) => {
return conn
.batch(sql, value)
.then((res) => {
conn.end();
return res;
})
.catch((err) => {
conn.end();
return Promise.reject(err);
});
})
.catch((err) => {
return Promise.reject(err);
});
};
}
module.exports = FilteredPoolCluster;

590
node_modules/mariadb/lib/io/bulk-packet.js generated vendored Normal file
View File

@@ -0,0 +1,590 @@
'use strict';
const moment = require('moment-timezone');
const Iconv = require('iconv-lite');
const SMALL_BUFFER_SIZE = 1024;
const MEDIUM_BUFFER_SIZE = 16384; //16k
const LARGE_BUFFER_SIZE = 131072; //128k
const BIG_BUFFER_SIZE = 1048576; //1M
const MAX_BUFFER_SIZE = 16777219; //16M + 4
/**
* Packet splitter.
*
* The servers have a limit max_allowed_packet which limits the size of the data sent, to avoid saturating the server in memory.
*
* The following implementation has a workaround that will rewrite the command and separate the send according to this value.
* This implies that this command can send multiple commands, with some tricks for sequencing packets.
*
*/
class BulkPacket {
constructor(opts, out, row) {
this.out = out;
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
this.pos = 4;
this.datatypes = [];
this.encoding = out.encoding;
this.statementId = -1;
this.waitingResponseNo = 1;
this.singleQuery = false;
this.haveErrorResponse = false;
this.writeBinaryDate = opts.tz
? opts.tz === 'Etc/UTC'
? this.writeBinaryUtcDate
: this.writeBinaryTimezoneDate
: this.writeBinaryLocalDate;
if (this.encoding === 'utf8') {
this.writeLengthEncodedString = this.writeDefaultLengthEncodedString;
} else if (Buffer.isEncoding(this.encoding)) {
this.writeLengthEncodedString = this.writeDefaultLengthEncodedString;
} else {
this.writeLengthEncodedString = this.writeIconvLengthEncodedString;
}
this.maxAllowedPacket = opts.maxAllowedPacket;
this.maxPacketSize = opts.maxAllowedPacket
? Math.min(MAX_BUFFER_SIZE, opts.maxAllowedPacket)
: 4194304;
this.writeHeader(row);
}
datatypeChanged(row) {
if (this.datatypes.length !== row.length) return true;
for (let r = 0; r < row.length; r++) {
if (row[r] !== null) {
switch (typeof row[r]) {
case 'boolean':
if (this.datatypes[r] !== 0x01) return true;
break;
case 'number':
case 'bigint':
if (this.datatypes[r] !== 0x0f) return true;
break;
case 'object':
if (Object.prototype.toString.call(row[r]) === '[object Date]') {
if (this.datatypes[r] !== 0x0c) return true;
} else if (Buffer.isBuffer(row[r])) {
if (this.datatypes[r] !== 0xfb) return true;
} else if (
row[r].type != null &&
[
'Point',
'LineString',
'Polygon',
'MultiPoint',
'MultiLineString',
'MultiPolygon',
'GeometryCollection'
].includes(row[r].type)
) {
if (this.datatypes[r] !== 0xfb) return true;
} else {
if (this.datatypes[r] !== 0x0f) return true;
}
break;
default:
if (this.datatypes[r] !== 0x0f) return true;
}
}
}
return false;
}
writeHeader(row) {
this.buf[this.pos++] = 0xfa;
//use last prepare command
this.buf[this.pos++] = this.statementId;
this.buf[this.pos++] = this.statementId >> 8;
this.buf[this.pos++] = this.statementId >> 16;
this.buf[this.pos++] = this.statementId >> 24;
//set bulk flags to Send types to server
this.buf[this.pos++] = 0x80;
this.buf[this.pos++] = 0x00;
//send data type (strings)
this.datatypes = [];
if (row) {
for (let r = 0; r < row.length; r++) {
if (row[r] === null) {
this.buf[this.pos++] = 0x0f;
} else {
switch (typeof row[r]) {
case 'boolean':
this.buf[this.pos++] = 0x01;
break;
case 'bigint':
case 'number':
this.buf[this.pos++] = 0x0f;
break;
case 'object':
if (Object.prototype.toString.call(row[r]) === '[object Date]') {
this.buf[this.pos++] = 0x0c;
} else if (Buffer.isBuffer(row[r])) {
this.buf[this.pos++] = 0xfb;
} else if (
row[r].type != null &&
[
'Point',
'LineString',
'Polygon',
'MultiPoint',
'MultiLineString',
'MultiPolygon',
'GeometryCollection'
].includes(row[r].type)
) {
this.buf[this.pos++] = 0xfb;
} else {
this.buf[this.pos++] = 0x0f;
}
break;
default:
this.buf[this.pos++] = 0x0f;
}
}
this.datatypes[r] = this.buf[this.pos - 1];
this.buf[this.pos++] = 0x00;
}
}
}
growBuffer(len) {
let newCapacity;
if (len + this.pos < MEDIUM_BUFFER_SIZE) {
newCapacity = MEDIUM_BUFFER_SIZE;
} else if (len + this.pos < LARGE_BUFFER_SIZE) {
newCapacity = LARGE_BUFFER_SIZE;
} else if (len + this.pos < BIG_BUFFER_SIZE) {
newCapacity = BIG_BUFFER_SIZE;
} else newCapacity = MAX_BUFFER_SIZE;
if (newCapacity > this.maxPacketSize && this.markPos) {
this.flush(false, len);
return true;
} else {
let newBuf = Buffer.allocUnsafe(Math.min(newCapacity));
this.buf.copy(newBuf, 0, 0, this.pos);
this.buf = newBuf;
return false;
}
}
writeLengthStringAscii(val) {
let len = val.length;
//not enough space remaining
if (len >= this.buf.length - this.pos) {
let strBuf = Buffer.from(val, 'ascii');
return this.writeLengthEncodedBuffer(strBuf);
}
this.writeLength(len);
for (let off = 0; off < len; ) {
this.buf[this.pos++] = val.charCodeAt(off++);
}
return false;
}
writeLength(len) {
if (len < 0xfb) {
return this.writeInt8(len);
} else if (len < 65536) {
let flushed = this.writeInt8(0xfc);
return this.writeInt16(len) || flushed;
} else if (len < 16777216) {
let flushed = this.writeInt8(0xfd);
return this.writeInt24(len) || flushed;
} else {
//4 last bytes are filled with 0, packet limitation size is 32 bit integer
if (this.pos + 9 >= this.buf.length) {
const tmpBuf = Buffer.allocUnsafe(9);
tmpBuf[0] = 0xfe;
tmpBuf[1] = len;
tmpBuf[2] = len >>> 8;
tmpBuf[3] = len >>> 16;
tmpBuf[4] = len >>> 24;
tmpBuf[5] = 0;
tmpBuf[6] = 0;
tmpBuf[7] = 0;
tmpBuf[8] = 0;
return this.writeBuffer(tmpBuf);
}
this.buf[this.pos++] = 0xfe;
this.buf[this.pos++] = len;
this.buf[this.pos++] = len >>> 8;
this.buf[this.pos++] = len >>> 16;
this.buf[this.pos++] = len >>> 24;
this.buf[this.pos++] = 0;
this.buf[this.pos++] = 0;
this.buf[this.pos++] = 0;
this.buf[this.pos++] = 0;
return false;
}
}
writeLengthEncodedBuffer(val) {
let valLen = val.length;
let flushed = this.writeLength(valLen);
return this.writeBuffer(val) || flushed;
}
writeBuffer(val) {
let flushed = false;
let valLen = val.length;
if (valLen > this.buf.length - this.pos) {
//makes buffer bigger (up to 16M)
if (this.buf.length < MAX_BUFFER_SIZE) flushed = this.growBuffer(valLen * 2);
//data may still be bigger than buffer.
//must flush buffer when full (and reset position to 4)
if (valLen > this.buf.length - this.pos) {
let tmpPos = this.buf.length - this.pos;
val.copy(this.buf, this.pos, 0, tmpPos);
this.pos += tmpPos;
this.flush(false, valLen - tmpPos);
while (tmpPos < valLen) {
if (this.buf.length - this.pos < valLen - tmpPos) this.growBuffer(valLen - tmpPos);
const toWrite = Math.min(valLen - tmpPos, this.buf.length - this.pos);
val.copy(this.buf, this.pos, tmpPos, tmpPos + toWrite);
tmpPos += toWrite;
this.pos += toWrite;
if (valLen - tmpPos > 0) this.flush(false, valLen - tmpPos);
}
return true;
}
}
//sure to have enough place to use buffer directly
val.copy(this.buf, this.pos, 0, valLen);
this.pos += valLen;
return flushed;
}
writeInt8(value) {
let flushed = false;
if (this.pos + 1 > this.buf.length) {
if (this.buf.length < MAX_BUFFER_SIZE) {
flushed = this.growBuffer(1);
} else {
this.flush(false, 1);
this.buf[this.pos++] = value;
return true;
}
}
this.buf[this.pos++] = value;
return flushed;
}
writeInt16(value) {
let flushed = false;
if (this.pos + 2 > this.buf.length) {
if (this.buf.length < this.maxPacketSize) flushed = this.growBuffer(2);
if (this.pos + 2 > this.buf.length) {
const tmpBuf = Buffer.allocUnsafe(2);
tmpBuf[0] = value;
tmpBuf[1] = value >>> 8;
this.writeBuffer(tmpBuf);
return true;
}
}
this.buf[this.pos++] = value;
this.buf[this.pos++] = value >>> 8;
return flushed;
}
writeInt24(value) {
let flushed = false;
if (this.pos + 3 > this.buf.length) {
if (this.buf.length < this.maxPacketSize) flushed = this.growBuffer(3);
if (this.pos + 3 > this.buf.length) {
const tmpBuf = Buffer.allocUnsafe(3);
tmpBuf[0] = value;
tmpBuf[1] = value >>> 8;
tmpBuf[2] = value >>> 16;
this.writeBuffer(tmpBuf);
return true;
}
}
this.buf[this.pos++] = value;
this.buf[this.pos++] = value >>> 8;
this.buf[this.pos++] = value >>> 16;
return flushed;
}
writeIconvLengthEncodedString(str) {
let buf = Iconv.encode(str, this.encoding);
return this.writeLengthEncodedBuffer(buf, 0, buf.length);
}
writeDefaultLengthEncodedString(str) {
//javascript use UCS-2 or UTF-16 string internal representation
//that means that string to byte will be a maximum of * 3
// (4 bytes utf-8 are represented on 2 UTF-16 characters)
if (str.length * 3 + 10 < this.buf.length - this.pos) {
//reserve position for length indicator
const maxLen = str.length * 3;
let lengthPos;
if (maxLen < 0xfb) {
lengthPos = this.pos;
this.pos++;
} else if (maxLen < 65536) {
this.buf[this.pos++] = 0xfc;
lengthPos = this.pos;
this.pos += 2;
} else {
//if len was > 16M, would have been > to buffer length
this.buf[this.pos++] = 0xfd;
lengthPos = this.pos;
this.pos += 3;
}
const prevPos = this.pos;
this.pos += this.buf.write(str, this.pos, this.encoding);
//write real data length
const realLen = this.pos - prevPos;
if (maxLen < 0xfb) {
this.buf[lengthPos] = realLen;
} else if (maxLen < 65536) {
this.buf[lengthPos] = realLen;
this.buf[lengthPos + 1] = realLen >>> 8;
} else {
this.buf[lengthPos] = realLen;
this.buf[lengthPos + 1] = realLen >>> 8;
this.buf[lengthPos + 2] = realLen >>> 16;
}
return false;
}
//checking real length
let flushed = false;
let byteLength = Buffer.byteLength(str, this.encoding);
if (byteLength + 9 > this.buf.length - this.pos) {
if (this.buf.length < MAX_BUFFER_SIZE) flushed = this.growBuffer(byteLength + 9);
if (byteLength > this.buf.length - this.pos) {
//not enough space in buffer, will stream :
let strBuf = Buffer.from(str, this.encoding);
return this.writeLengthEncodedBuffer(strBuf) || flushed;
}
}
this.writeLength(byteLength);
this.pos += this.buf.write(str, this.pos, this.encoding);
return flushed;
}
writeBinaryLocalDate(date, opts) {
const year = date.getFullYear();
const mon = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const min = date.getMinutes();
const sec = date.getSeconds();
const ms = date.getMilliseconds();
return this._writeBinaryDate(year, mon, day, hour, min, sec, ms);
}
writeBinaryUtcDate(date, opts) {
const year = date.getUTCFullYear();
const mon = date.getUTCMonth() + 1;
const day = date.getUTCDate();
const hour = date.getUTCHours();
const min = date.getUTCMinutes();
const sec = date.getUTCSeconds();
const ms = date.getUTCMilliseconds();
return this._writeBinaryDate(year, mon, day, hour, min, sec, ms);
}
_writeBinaryDate(year, mon, day, hour, min, sec, ms) {
let len = ms === 0 ? 7 : 11;
//not enough space remaining
if (len + 1 > this.buf.length - this.pos) {
let tmpBuf = Buffer.allocUnsafe(len + 1);
tmpBuf[0] = len;
tmpBuf[1] = year;
tmpBuf[2] = year >>> 8;
tmpBuf[3] = mon;
tmpBuf[4] = day;
tmpBuf[5] = hour;
tmpBuf[6] = min;
tmpBuf[7] = sec;
if (ms !== 0) {
const micro = ms * 1000;
tmpBuf[8] = micro;
tmpBuf[9] = micro >>> 8;
tmpBuf[10] = micro >>> 16;
tmpBuf[11] = micro >>> 24;
}
return this.writeBuffer(tmpBuf);
}
this.buf[this.pos] = len;
this.buf[this.pos + 1] = year;
this.buf[this.pos + 2] = year >>> 8;
this.buf[this.pos + 3] = mon;
this.buf[this.pos + 4] = day;
this.buf[this.pos + 5] = hour;
this.buf[this.pos + 6] = min;
this.buf[this.pos + 7] = sec;
if (ms !== 0) {
const micro = ms * 1000;
this.buf[this.pos + 8] = micro;
this.buf[this.pos + 9] = micro >>> 8;
this.buf[this.pos + 10] = micro >>> 16;
this.buf[this.pos + 11] = micro >>> 24;
}
this.pos += len + 1;
return false;
}
writeBinaryTimezoneDate(date, opts) {
const dateZoned = new Date(
moment.tz(date, opts.localTz).tz(opts.tz).format('YYYY-MM-DD HH:mm:ss.SSSSSS')
);
const year = dateZoned.getFullYear();
const mon = dateZoned.getMonth() + 1;
const day = dateZoned.getDate();
const hour = dateZoned.getHours();
const min = dateZoned.getMinutes();
const sec = dateZoned.getSeconds();
const ms = dateZoned.getMilliseconds();
return this._writeBinaryDate(year, mon, day, hour, min, sec, ms);
}
mark(isLast, nextRow) {
let flushed = false;
this.nextRow = nextRow;
if (this.singleQuery) {
//end of big query that is more than 16M
//write single one
if (!this.haveErrorResponse) {
const packetSendSize =
this.pos +
(this.singleQuerySequenceNo !== undefined
? (this.singleQuerySequenceNo + 1) * MAX_BUFFER_SIZE
: 0);
if (this.maxAllowedPacket && packetSendSize > this.maxAllowedPacket) {
console.log(
"will send a packet to db server with size > connection option 'maxAllowedPacket' (size send is " +
packetSendSize +
') connection might be reset by server'
);
}
this.copyAndFlush(true);
flushed = true;
this.markPos = undefined;
}
this.singleQuerySequenceNo = undefined;
this.singleQueryCompressSequenceNo = undefined;
this.singleQuery = false;
this.writeHeader(nextRow);
this.markPos = undefined;
} else {
if (!isLast && this.datatypeChanged(nextRow)) {
this.markPos = this.pos;
this.flushMark();
flushed = true;
} else if (this.markPos && this.pos > this.maxPacketSize) {
//not enough room for current query , flush mark.
this.flushMark();
flushed = true;
} else {
//just mark ending query
this.markPos = this.pos;
if (isLast) {
this.flushMark();
flushed = true;
}
}
}
return flushed;
}
flush(end, remainingLen) {
if (this.markPos && !this.singleQuery) {
this.flushMark();
} else {
//one insert is more than 16M, will continue to mono insert, hoping
//that max_allowed_packet is sized accordingly to query.
if (this.buf.length < MAX_BUFFER_SIZE) {
//in this case, connector has default to 4M packet, and a single query size
//is > to 4mb. growing buffer to 16M
let newBuf = Buffer.allocUnsafe(MAX_BUFFER_SIZE);
this.buf.copy(newBuf, 0, 0, this.pos);
this.buf = newBuf;
} else {
if (!this.haveErrorResponse) {
if (this.maxAllowedPacket && this.buf.length > this.maxAllowedPacket) {
console.log(
"will send a packet to server with size > connection option 'maxAllowedPacket' (size send is " +
this.pos +
') connection might be reset by server'
);
}
this.copyAndFlush(false);
this.markPos = undefined;
if (!this.singleQuery) this.waitingResponseNo++;
this.singleQuery = true;
this.singleQuerySequenceNo = this.out.cmd.sequenceNo;
this.singleQueryCompressSequenceNo = this.out.cmd.compressSequenceNo;
}
}
}
}
flushMark() {
let afterMark;
if (this.pos !== this.markPos) {
afterMark = Buffer.allocUnsafe(this.pos - this.markPos);
this.buf.copy(afterMark, 0, this.markPos, this.pos);
}
this.pos = this.markPos;
if (!this.haveErrorResponse) {
this.copyAndFlush(true);
this.waitingResponseNo++;
}
this.pos = 4;
this.markPos = undefined;
if (this.nextRow) this.writeHeader(this.nextRow);
if (afterMark) {
if (this.buf.length - this.pos < afterMark.length)
this.growBuffer(afterMark.length - (this.buf.length - this.pos));
afterMark.copy(this.buf, this.pos, 0, afterMark.length);
this.pos += afterMark.length;
}
this.singleQuery = false;
this.singleQuerySequenceNo = undefined;
this.singleQueryCompressSequenceNo = undefined;
}
copyAndFlush(ended) {
this.out.buf = this.buf;
this.out.pos = this.pos;
if (this.singleQuerySequenceNo !== undefined) {
this.out.cmd.sequenceNo = this.singleQuerySequenceNo;
this.out.cmd.compressSequenceNo = this.singleQueryCompressSequenceNo;
} else {
this.out.cmd.sequenceNo = -1;
this.out.cmd.compressSequenceNo = -1;
}
this.out.flushBuffer(ended);
if (this.singleQuerySequenceNo !== undefined) {
this.singleQuerySequenceNo = this.out.cmd.sequenceNo;
this.singleQueryCompressSequenceNo = this.out.cmd.compressSequenceNo;
}
this.pos = 4;
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
}
endedWithError() {
this.haveErrorResponse = true;
}
}
module.exports = BulkPacket;

141
node_modules/mariadb/lib/io/compression-input-stream.js generated vendored Normal file
View File

@@ -0,0 +1,141 @@
'use strict';
const ZLib = require('zlib');
const Utils = require('../misc/utils');
/**
* MySQL packet parser
* see : https://mariadb.com/kb/en/library/0-packet/
*/
class CompressionInputStream {
constructor(reader, receiveQueue, opts, info) {
this.reader = reader;
this.receiveQueue = receiveQueue;
this.info = info;
this.opts = opts;
this.header = Buffer.allocUnsafe(7);
this.headerLen = 0;
this.compressPacketLen = null;
this.packetLen = null;
this.remainingLen = null;
this.parts = null;
this.partsTotalLen = 0;
}
receivePacket(chunk) {
let cmd = this.currentCmd();
if (this.opts.debugCompress) {
console.log(
'<== conn:%d %s (compress)\n%s',
this.info.threadId ? this.info.threadId : -1,
cmd
? cmd.onPacketReceive
? cmd.constructor.name + '.' + cmd.onPacketReceive.name
: cmd.constructor.name
: 'no command',
Utils.log(this.opts, chunk, 0, chunk.length, this.header)
);
}
if (cmd) cmd.compressSequenceNo = this.header[3];
const unCompressLen = this.header[4] | (this.header[5] << 8) | (this.header[6] << 16);
if (unCompressLen === 0) {
this.reader.onData(chunk);
} else {
//use synchronous inflating, to ensure FIFO packet order
const unCompressChunk = ZLib.inflateSync(chunk);
this.reader.onData(unCompressChunk);
}
}
currentCmd() {
let cmd;
while ((cmd = this.receiveQueue.peek())) {
if (cmd.onPacketReceive) return cmd;
this.receiveQueue.shift();
}
return null;
}
resetHeader() {
this.remainingLen = null;
this.headerLen = 0;
}
onData(chunk) {
let pos = 0;
let length;
const chunkLen = chunk.length;
do {
if (this.remainingLen) {
length = this.remainingLen;
} else if (this.headerLen === 0 && chunkLen - pos >= 7) {
this.header[0] = chunk[pos];
this.header[1] = chunk[pos + 1];
this.header[2] = chunk[pos + 2];
this.header[3] = chunk[pos + 3];
this.header[4] = chunk[pos + 4];
this.header[5] = chunk[pos + 5];
this.header[6] = chunk[pos + 6];
this.headerLen = 7;
pos += 7;
this.compressPacketLen = this.header[0] + (this.header[1] << 8) + (this.header[2] << 16);
this.packetLen = this.header[4] | (this.header[5] << 8) | (this.header[6] << 16);
if (this.packetLen === 0) this.packetLen = this.compressPacketLen;
length = this.compressPacketLen;
} else {
length = null;
while (chunkLen - pos > 0) {
this.header[this.headerLen++] = chunk[pos++];
if (this.headerLen === 7) {
this.compressPacketLen =
this.header[0] + (this.header[1] << 8) + (this.header[2] << 16);
this.packetLen = this.header[4] | (this.header[5] << 8) | (this.header[6] << 16);
if (this.packetLen === 0) this.packetLen = this.compressPacketLen;
length = this.compressPacketLen;
break;
}
}
}
if (length) {
if (chunkLen - pos >= length) {
const buf = chunk.slice(pos, pos + length);
pos += length;
if (this.parts) {
this.parts.push(buf);
this.partsTotalLen += length;
if (this.compressPacketLen < 0xffffff) {
let buf = Buffer.concat(this.parts, this.partsTotalLen);
this.parts = null;
this.receivePacket(buf);
}
} else {
if (this.compressPacketLen < 0xffffff) {
this.receivePacket(buf);
} else {
this.parts = [buf];
this.partsTotalLen = length;
}
}
this.resetHeader();
} else {
const buf = chunk.slice(pos, chunkLen);
if (!this.parts) {
this.parts = [buf];
this.partsTotalLen = chunkLen - pos;
} else {
this.parts.push(buf);
this.partsTotalLen += chunkLen - pos;
}
this.remainingLen = length - (chunkLen - pos);
return;
}
}
} while (pos < chunkLen);
}
}
module.exports = CompressionInputStream;

View File

@@ -0,0 +1,171 @@
'use strict';
const Utils = require('../misc/utils');
const ZLib = require('zlib');
//increase by level to avoid buffer copy.
const SMALL_BUFFER_SIZE = 2048;
const MEDIUM_BUFFER_SIZE = 131072; //128k
const LARGE_BUFFER_SIZE = 1048576; //1M
const MAX_BUFFER_SIZE = 16777222; //16M + 7
/**
/**
* MySQL compression filter.
* see https://mariadb.com/kb/en/library/0-packet/#compressed-packet
*/
class CompressionOutputStream {
/**
* Constructor
*
* @param socket current socket
* @param opts current connection options
* @param info current connection information
* @constructor
*/
constructor(socket, opts, info) {
this.info = info;
this.opts = opts;
this.pos = 7;
this.header = Buffer.allocUnsafe(7);
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
this.writer = (buffer) => {
socket.write(buffer);
};
}
growBuffer(len) {
let newCapacity;
if (len + this.pos < MEDIUM_BUFFER_SIZE) {
newCapacity = MEDIUM_BUFFER_SIZE;
} else if (len + this.pos < LARGE_BUFFER_SIZE) {
newCapacity = LARGE_BUFFER_SIZE;
} else newCapacity = MAX_BUFFER_SIZE;
let newBuf = Buffer.allocUnsafe(newCapacity);
this.buf.copy(newBuf, 0, 0, this.pos);
this.buf = newBuf;
}
writeBuf(arr, cmd) {
let off = 0,
len = arr.length;
if (len > this.buf.length - this.pos) {
if (this.buf.length !== MAX_BUFFER_SIZE) {
this.growBuffer(len);
}
//max buffer size
if (len > this.buf.length - this.pos) {
//not enough space in buffer, will stream :
// fill buffer and flush until all data are snd
let remainingLen = len;
while (true) {
//filling buffer
let lenToFillBuffer = Math.min(MAX_BUFFER_SIZE - this.pos, remainingLen);
arr.copy(this.buf, this.pos, off, off + lenToFillBuffer);
remainingLen -= lenToFillBuffer;
off += lenToFillBuffer;
this.pos += lenToFillBuffer;
if (remainingLen === 0) return;
this.flush(false, cmd, remainingLen);
}
}
}
arr.copy(this.buf, this.pos, off, off + len);
this.pos += len;
}
/**
* Flush the internal buffer.
*/
flush(cmdEnd, cmd, remainingLen) {
if (this.pos < 1536) {
//*******************************************************************************
// small packet, no compression
//*******************************************************************************
this.buf[0] = this.pos - 7;
this.buf[1] = (this.pos - 7) >>> 8;
this.buf[2] = (this.pos - 7) >>> 16;
this.buf[3] = ++cmd.compressSequenceNo;
this.buf[4] = 0;
this.buf[5] = 0;
this.buf[6] = 0;
if (this.opts.debugCompress) {
console.log(
'==> conn:%d %s (compress)\n%s',
this.info.threadId ? this.info.threadId : -1,
cmd ? cmd.constructor.name + '(0,' + this.pos + ')' : 'unknown',
Utils.log(this.opts, this.buf, 0, this.pos)
);
}
this.writer(this.buf.slice(0, this.pos));
} else {
//*******************************************************************************
// compressing packet
//*******************************************************************************
//use synchronous inflating, to ensure FIFO packet order
const compressChunk = ZLib.deflateSync(this.buf.slice(7, this.pos));
const compressChunkLen = compressChunk.length;
this.header[0] = compressChunkLen;
this.header[1] = compressChunkLen >>> 8;
this.header[2] = compressChunkLen >>> 16;
this.header[3] = ++cmd.compressSequenceNo;
this.header[4] = this.pos - 7;
this.header[5] = (this.pos - 7) >>> 8;
this.header[6] = (this.pos - 7) >>> 16;
if (this.opts.debugCompress) {
console.log(
'==> conn:%d %s (compress)\n%s',
this.info.threadId ? this.info.threadId : -1,
cmd ? cmd.constructor.name + '(0,' + this.pos + '=>' + compressChunkLen + ')' : 'unknown',
Utils.log(this.opts, compressChunk, 0, compressChunkLen, this.header)
);
}
this.writer(this.header);
this.writer(compressChunk);
if (cmdEnd && this.pos === MAX_BUFFER_SIZE) this.writeEmptyPacket(cmd);
this.header = Buffer.allocUnsafe(7);
}
this.buf = remainingLen
? CompressionOutputStream.allocateBuffer(remainingLen)
: Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
this.pos = 7;
}
static allocateBuffer(len) {
if (len + 4 < SMALL_BUFFER_SIZE) {
return Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
} else if (len + 4 < MEDIUM_BUFFER_SIZE) {
return Buffer.allocUnsafe(MEDIUM_BUFFER_SIZE);
} else if (len + 4 < LARGE_BUFFER_SIZE) {
return Buffer.allocUnsafe(LARGE_BUFFER_SIZE);
}
return Buffer.allocUnsafe(MAX_BUFFER_SIZE);
}
writeEmptyPacket(cmd) {
const emptyBuf = Buffer.from([0x00, 0x00, 0x00, cmd.compressSequenceNo, 0x00, 0x00, 0x00]);
if (this.opts.debugCompress) {
console.log(
'==> conn:%d %s (compress)\n%s',
this.info.threadId ? this.info.threadId : -1,
cmd ? cmd.constructor.name + '(0,' + this.pos + ')' : 'unknown',
Utils.log(this.opts, emptyBuf, 0, 7)
);
}
this.writer(emptyBuf);
}
}
module.exports = CompressionOutputStream;

193
node_modules/mariadb/lib/io/packet-input-stream.js generated vendored Normal file
View File

@@ -0,0 +1,193 @@
'use strict';
const PacketNodeEncoded = require('./packet-node-encoded');
const PacketIconvEncoded = require('./packet-node-iconv');
const Utils = require('../misc/utils');
/**
* MySQL packet parser
* see : https://mariadb.com/kb/en/library/0-packet/
*/
class PacketInputStream {
constructor(unexpectedPacket, receiveQueue, out, opts, info) {
this.unexpectedPacket = unexpectedPacket;
this.opts = opts;
this.receiveQueue = receiveQueue;
this.info = info;
this.out = out;
//in case packet is not complete
this.header = Buffer.allocUnsafe(4);
this.headerLen = 0;
this.packetLen = null;
this.remainingLen = null;
this.parts = null;
this.partsTotalLen = 0;
this.changeEncoding(this.opts.collation);
this.changeDebug(this.opts.logPackets, this.opts.debug);
this.opts.on('collation', this.changeEncoding.bind(this));
this.opts.on('debug', this.changeDebug.bind(this));
}
changeEncoding(collation) {
this.encoding = collation.charset;
this.packetConstructor = Buffer.isEncoding(this.encoding)
? PacketNodeEncoded
: PacketIconvEncoded;
}
changeDebug(logPackets, debug) {
this.logPackets = logPackets;
this.debug = debug;
this.receivePacket =
this.logPackets || this.debug ? this.receivePacketDebug : this.receivePacketBasic;
}
receivePacketDebug(packet) {
let cmd = this.currentCmd();
if (packet) {
const packetStr = Utils.log(this.opts, packet.buf, packet.pos, packet.end, this.header);
if (this.opts.logPackets) {
this.info.addPacket(
'<== conn:' +
(this.info.threadId ? this.info.threadId : -1) +
' ' +
(cmd
? cmd.onPacketReceive
? cmd.constructor.name + '.' + cmd.onPacketReceive.name
: cmd.constructor.name
: 'no command') +
' (' +
packet.pos +
',' +
packet.end +
'))\n' +
packetStr
);
}
if (this.opts.debug) {
console.log(
'<== conn:%d %s (%d,%d)\n%s',
this.info.threadId ? this.info.threadId : -1,
cmd
? cmd.onPacketReceive
? cmd.constructor.name + '.' + cmd.onPacketReceive.name
: cmd.constructor.name
: 'no command',
packet.pos,
packet.end,
packetStr
);
}
}
if (!cmd) {
this.unexpectedPacket(packet);
return;
}
cmd.sequenceNo = this.header[3];
cmd.onPacketReceive(packet, this.out, this.opts, this.info);
if (!cmd.onPacketReceive) this.receiveQueue.shift();
}
receivePacketBasic(packet) {
let cmd = this.currentCmd();
if (!cmd) {
this.unexpectedPacket(packet);
return;
}
cmd.sequenceNo = this.header[3];
cmd.onPacketReceive(packet, this.out, this.opts, this.info);
if (!cmd.onPacketReceive) this.receiveQueue.shift();
}
resetHeader() {
this.remainingLen = null;
this.headerLen = 0;
}
currentCmd() {
let cmd;
while ((cmd = this.receiveQueue.peek())) {
if (cmd.onPacketReceive) return cmd;
this.receiveQueue.shift();
}
return null;
}
onData(chunk) {
let pos = 0;
let length;
const chunkLen = chunk.length;
do {
//read header
if (this.remainingLen) {
length = this.remainingLen;
} else if (this.headerLen === 0 && chunkLen - pos >= 4) {
this.header[0] = chunk[pos];
this.header[1] = chunk[pos + 1];
this.header[2] = chunk[pos + 2];
this.header[3] = chunk[pos + 3];
pos += 4;
this.headerLen = 4;
this.packetLen = this.header[0] + (this.header[1] << 8) + (this.header[2] << 16);
length = this.packetLen;
} else {
length = null;
while (chunkLen - pos > 0) {
this.header[this.headerLen++] = chunk[pos++];
if (this.headerLen === 4) {
this.packetLen = this.header[0] + (this.header[1] << 8) + (this.header[2] << 16);
length = this.packetLen;
break;
}
}
}
if (length) {
if (chunkLen - pos >= length) {
const buf = chunk.slice(pos, pos + length);
pos += length;
if (this.parts) {
this.parts.push(buf);
this.partsTotalLen += length;
if (this.packetLen < 0xffffff) {
let buf = Buffer.concat(this.parts, this.partsTotalLen);
this.parts = null;
const packet = new this.packetConstructor(buf, 0, this.partsTotalLen, this.encoding);
this.receivePacket(packet);
}
} else {
if (this.packetLen < 0xffffff) {
const packet = new this.packetConstructor(buf, 0, length, this.encoding);
this.receivePacket(packet);
} else {
this.parts = [buf];
this.partsTotalLen = length;
}
}
this.resetHeader();
} else {
const buf = chunk.slice(pos, chunkLen);
if (!this.parts) {
this.parts = [buf];
this.partsTotalLen = chunkLen - pos;
} else {
this.parts.push(buf);
this.partsTotalLen += chunkLen - pos;
}
this.remainingLen = length - (chunkLen - pos);
return;
}
}
} while (pos < chunkLen);
}
}
module.exports = PacketInputStream;

36
node_modules/mariadb/lib/io/packet-node-encoded.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
'use strict';
const Packet = require('./packet');
class PacketNodeEncoded extends Packet {
constructor(buf, pos, end, encoding) {
super(buf, pos, end);
this.encoding = encoding;
}
readStringLength() {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
return this.buf.toString(this.encoding, this.pos - len, this.pos);
}
readString(beg, len) {
return this.buf.toString(this.encoding, beg, beg + len);
}
subPacketLengthEncoded() {
const len = this.readUnsignedLength();
this.skip(len);
return new PacketNodeEncoded(this.buf, this.pos - len, this.pos, this.encoding);
}
readStringRemaining() {
const str = this.buf.toString(this.encoding, this.pos, this.end);
this.pos = this.end;
return str;
}
}
module.exports = PacketNodeEncoded;

37
node_modules/mariadb/lib/io/packet-node-iconv.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
'use strict';
const Packet = require('./packet');
const Iconv = require('iconv-lite');
class PacketIconvEncoded extends Packet {
constructor(buf, pos, end, encoding) {
super(buf, pos, end);
this.encoding = encoding;
}
readStringLength() {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
return Iconv.decode(this.buf.slice(this.pos - len, this.pos), this.encoding);
}
readString(beg, len) {
return Iconv.decode(this.buf.slice(beg, beg + len), this.encoding);
}
subPacketLengthEncoded() {
const len = this.readUnsignedLength();
this.skip(len);
return new PacketIconvEncoded(this.buf, this.pos - len, this.pos, this.encoding);
}
readStringRemaining() {
const str = Iconv.decode(this.buf.slice(this.pos, this.end), this.encoding);
this.pos = this.end;
return str;
}
}
module.exports = PacketIconvEncoded;

502
node_modules/mariadb/lib/io/packet-output-stream.js generated vendored Normal file
View File

@@ -0,0 +1,502 @@
'use strict';
const Iconv = require('iconv-lite');
const Utils = require('../misc/utils');
const QUOTE = 0x27;
const DBL_QUOTE = 0x22;
const ZERO_BYTE = 0x00;
const SLASH = 0x5c;
//increase by level to avoid buffer copy.
const SMALL_BUFFER_SIZE = 1024;
const MEDIUM_BUFFER_SIZE = 16384; //16k
const LARGE_BUFFER_SIZE = 131072; //128k
const BIG_BUFFER_SIZE = 1048576; //1M
const MAX_BUFFER_SIZE = 16777219; //16M + 4
const CHARS_GLOBAL_REGEXP = /[\0\"\'\\\b\n\r\t\u001A]/g; // eslint-disable-line no-control-regex
/**
* MySQL packet builder.
*
* @param opts options
* @param info connection info
* @constructor
*/
class PacketOutputStream {
constructor(opts, info) {
this.opts = opts;
this.info = info;
this.pos = 4;
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
this.changeEncoding(this.opts.collation);
this.changeDebug(this.opts.logPackets, this.opts.debug);
this.opts.on('collation', this.changeEncoding.bind(this));
this.opts.on('debug', this.changeDebug.bind(this));
}
changeEncoding(collation) {
this.encoding = collation.charset;
if (this.encoding === 'utf8') {
this.writeString = this.writeDefaultBufferString;
this.writeStringEscapeQuote = this.writeUtf8StringEscapeQuote;
} else if (Buffer.isEncoding(this.encoding)) {
this.writeString = this.writeDefaultBufferString;
this.writeStringEscapeQuote = this.writeDefaultStringEscapeQuote;
} else {
this.writeString = this.writeDefaultIconvString;
this.writeStringEscapeQuote = this.writeDefaultStringEscapeQuote;
}
}
changeDebug(logPackets, debug) {
this.logPackets = logPackets;
this.debug = debug;
this.flushBuffer =
this.logPackets || this.debug ? this.flushBufferDebug : this.flushBufferBasic;
}
setStream(stream) {
this.stream = stream;
}
growBuffer(len) {
let newCapacity;
if (len + this.pos < MEDIUM_BUFFER_SIZE) {
newCapacity = MEDIUM_BUFFER_SIZE;
} else if (len + this.pos < LARGE_BUFFER_SIZE) {
newCapacity = LARGE_BUFFER_SIZE;
} else if (len + this.pos < BIG_BUFFER_SIZE) {
newCapacity = BIG_BUFFER_SIZE;
} else newCapacity = MAX_BUFFER_SIZE;
let newBuf = Buffer.allocUnsafe(newCapacity);
this.buf.copy(newBuf, 0, 0, this.pos);
this.buf = newBuf;
}
startPacket(cmd) {
this.cmd = cmd;
this.pos = 4;
}
writeInt8(value) {
if (this.pos + 1 >= this.buf.length) {
if (this.pos >= MAX_BUFFER_SIZE) {
//buffer is more than a Packet, must flushBuffer()
this.flushBuffer(false, 1);
} else this.growBuffer(1);
}
this.buf[this.pos++] = value;
}
writeInt16(value) {
if (this.pos + 2 >= this.buf.length) {
let b = Buffer.allocUnsafe(2);
b.writeUInt16LE(value, 0);
this.writeBuffer(b, 0, 2);
return;
}
this.buf[this.pos] = value;
this.buf[this.pos + 1] = value >> 8;
this.pos += 2;
}
writeInt16AtPos(initPos) {
this.buf[initPos] = this.pos - initPos - 2;
this.buf[initPos + 1] = (this.pos - initPos - 2) >> 8;
}
writeInt32(value) {
if (this.pos + 4 >= this.buf.length) {
//not enough space remaining
let arr = Buffer.allocUnsafe(4);
arr.writeInt32LE(value, 0);
this.writeBuffer(arr, 0, 4);
return;
}
this.buf[this.pos] = value;
this.buf[this.pos + 1] = value >> 8;
this.buf[this.pos + 2] = value >> 16;
this.buf[this.pos + 3] = value >> 24;
this.pos += 4;
}
writeLengthCoded(len) {
//length encoded can be null(0xfb) or bigger than 65k, but only if using binary protocol
//so not implemented for now
if (len < 0xfb) {
this.writeInt8(len);
return;
}
//max length is len < 0xffff
this.writeInt8(0xfc);
this.writeInt16(len);
}
writeBuffer(arr, off, len) {
if (len > this.buf.length - this.pos) {
if (this.buf.length !== MAX_BUFFER_SIZE) {
this.growBuffer(len);
}
//max buffer size
if (len > this.buf.length - this.pos) {
//not enough space in buffer, will stream :
// fill buffer and flush until all data are snd
let remainingLen = len;
while (true) {
//filling buffer
let lenToFillBuffer = Math.min(MAX_BUFFER_SIZE - this.pos, remainingLen);
arr.copy(this.buf, this.pos, off, off + lenToFillBuffer);
remainingLen -= lenToFillBuffer;
off += lenToFillBuffer;
this.pos += lenToFillBuffer;
if (remainingLen === 0) return;
this.flushBuffer(false, remainingLen);
}
}
}
arr.copy(this.buf, this.pos, off, off + len);
this.pos += len;
}
/**
* Write ascii string to socket (no escaping)
*
* @param str string
*/
writeStringAscii(str) {
let len = str.length;
//not enough space remaining
if (len >= this.buf.length - this.pos) {
let strBuf = Buffer.from(str, 'ascii');
this.writeBuffer(strBuf, 0, strBuf.length);
return;
}
for (let off = 0; off < len; ) {
this.buf[this.pos++] = str.charCodeAt(off++);
}
}
writeUtf8StringEscapeQuote(str) {
const charsLength = str.length;
//not enough space remaining
if (charsLength * 3 + 2 >= this.buf.length - this.pos) {
const arr = Buffer.from(str, 'utf8');
this.writeInt8(QUOTE);
this.writeBufferEscape(arr);
this.writeInt8(QUOTE);
return;
}
//create UTF-8 byte array
//since javascript char are internally using UTF-16 using surrogate's pattern, 4 bytes unicode characters will
//represent 2 characters : example "\uD83C\uDFA4" = 🎤 unicode 8 "no microphones"
//so max size is 3 * charLength
//(escape characters are 1 byte encoded, so length might only be 2 when escaped)
// + 2 for the quotes for text protocol
let charsOffset = 0;
let currChar;
this.buf[this.pos++] = QUOTE;
//quick loop if only ASCII chars for faster escape
for (
;
charsOffset < charsLength && (currChar = str.charCodeAt(charsOffset)) < 0x80;
charsOffset++
) {
if (
currChar === SLASH ||
currChar === QUOTE ||
currChar === ZERO_BYTE ||
currChar === DBL_QUOTE
) {
this.buf[this.pos++] = SLASH;
}
this.buf[this.pos++] = currChar;
}
//if quick loop not finished
while (charsOffset < charsLength) {
currChar = str.charCodeAt(charsOffset++);
if (currChar < 0x80) {
if (
currChar === SLASH ||
currChar === QUOTE ||
currChar === ZERO_BYTE ||
currChar === DBL_QUOTE
) {
this.buf[this.pos++] = SLASH;
}
this.buf[this.pos++] = currChar;
} else if (currChar < 0x800) {
this.buf[this.pos++] = 0xc0 | (currChar >> 6);
this.buf[this.pos++] = 0x80 | (currChar & 0x3f);
} else if (currChar >= 0xd800 && currChar < 0xe000) {
//reserved for surrogate - see https://en.wikipedia.org/wiki/UTF-16
if (currChar < 0xdc00) {
//is high surrogate
if (charsOffset + 1 > charsLength) {
this.buf[this.pos++] = 0x3f;
} else {
const nextChar = str.charCodeAt(charsOffset);
if (nextChar >= 0xdc00 && nextChar < 0xe000) {
//is low surrogate
const surrogatePairs =
(currChar << 10) + nextChar + (0x010000 - (0xd800 << 10) - 0xdc00);
this.buf[this.pos++] = 0xf0 | (surrogatePairs >> 18);
this.buf[this.pos++] = 0x80 | ((surrogatePairs >> 12) & 0x3f);
this.buf[this.pos++] = 0x80 | ((surrogatePairs >> 6) & 0x3f);
this.buf[this.pos++] = 0x80 | (surrogatePairs & 0x3f);
charsOffset++;
} else {
//must have low surrogate
this.buf[this.pos++] = 0x3f;
}
}
} else {
//low surrogate without high surrogate before
this.buf[this.pos++] = 0x3f;
}
} else {
this.buf[this.pos++] = 0xe0 | (currChar >> 12);
this.buf[this.pos++] = 0x80 | ((currChar >> 6) & 0x3f);
this.buf[this.pos++] = 0x80 | (currChar & 0x3f);
}
}
this.buf[this.pos++] = QUOTE;
}
writeDefaultBufferString(str) {
//javascript use UCS-2 or UTF-16 string internal representation
//that means that string to byte will be a maximum of * 3
// (4 bytes utf-8 are represented on 2 UTF-16 characters)
if (str.length * 3 < this.buf.length - this.pos) {
this.pos += this.buf.write(str, this.pos, this.encoding);
return;
}
//checking real length
let byteLength = Buffer.byteLength(str, this.encoding);
if (byteLength > this.buf.length - this.pos) {
if (this.buf.length < MAX_BUFFER_SIZE) {
this.growBuffer(byteLength);
}
if (byteLength > this.buf.length - this.pos) {
//not enough space in buffer, will stream :
let strBuf = Buffer.from(str, this.encoding);
this.writeBuffer(strBuf, 0, strBuf.length);
return;
}
}
this.pos += this.buf.write(str, this.pos, this.encoding);
}
writeDefaultIconvString(str) {
let buf = Iconv.encode(str, this.encoding);
this.writeBuffer(buf, 0, buf.length);
}
/**
* Parameters need to be properly escaped :
* following characters are to be escaped by "\" :
* - \0
* - \\
* - \'
* - \"
* regex split part of string writing part, and escaping special char.
* Those chars are <= 7f meaning that this will work even with multi-byte encoding
*
* @param str string to escape.
*/
writeDefaultStringEscapeQuote(str) {
this.writeInt8(QUOTE);
let match;
let lastIndex = 0;
while ((match = CHARS_GLOBAL_REGEXP.exec(str)) !== null) {
this.writeString(str.slice(lastIndex, match.index));
this.writeInt8(SLASH);
this.writeInt8(match[0].charCodeAt(0));
lastIndex = CHARS_GLOBAL_REGEXP.lastIndex;
}
if (lastIndex === 0) {
// Nothing was escaped
this.writeString(str);
this.writeInt8(QUOTE);
return;
}
if (lastIndex < str.length) {
this.writeString(str.slice(lastIndex));
}
this.writeInt8(QUOTE);
}
writeBufferEscape(val) {
let valLen = val.length;
if (valLen * 2 > this.buf.length - this.pos) {
//makes buffer bigger (up to 16M)
if (this.buf.length !== MAX_BUFFER_SIZE) this.growBuffer(valLen * 2);
//data may still be bigger than buffer.
//must flush buffer when full (and reset position to 4)
if (valLen * 2 > this.buf.length - this.pos) {
//not enough space in buffer, will fill buffer
for (let i = 0; i < valLen; i++) {
switch (val[i]) {
case QUOTE:
case SLASH:
case DBL_QUOTE:
case ZERO_BYTE:
if (this.pos >= this.buf.length) this.flushBuffer(false, (valLen - i) * 2);
this.buf[this.pos++] = SLASH; //add escape slash
}
if (this.pos >= this.buf.length) this.flushBuffer(false, (valLen - i) * 2);
this.buf[this.pos++] = val[i];
}
return;
}
}
//sure to have enough place to use buffer directly
for (let i = 0; i < valLen; i++) {
switch (val[i]) {
case QUOTE:
case SLASH:
case DBL_QUOTE:
case ZERO_BYTE:
this.buf[this.pos++] = SLASH; //add escape slash
}
this.buf[this.pos++] = val[i];
}
}
/**
* Indicate if buffer contain any data.
* @returns {boolean}
*/
isEmpty() {
return this.pos <= 4;
}
/**
* Flush the internal buffer.
*/
flushBufferDebug(commandEnd, remainingLen) {
this.buf[0] = this.pos - 4;
this.buf[1] = (this.pos - 4) >>> 8;
this.buf[2] = (this.pos - 4) >>> 16;
this.buf[3] = ++this.cmd.sequenceNo;
this.stream.writeBuf(this.buf.slice(0, this.pos), this.cmd);
const packet = Utils.log(this.opts, this.buf, 0, this.pos);
if (this.opts.logPackets) {
this.info.addPacket(
'==> conn:' +
(this.info.threadId ? this.info.threadId : -1) +
' ' +
this.cmd.constructor.name +
'(0,' +
this.pos +
')\n' +
packet
);
}
if (this.opts.debug) {
console.log(
'==> conn:%d %s\n%s',
this.info.threadId ? this.info.threadId : -1,
this.cmd.constructor.name + '(0,' + this.pos + ')',
Utils.log(this.opts, this.buf, 0, this.pos)
);
}
if (commandEnd) {
//if last packet fill the max size, must send an empty com to indicate that command end.
if (this.pos === MAX_BUFFER_SIZE) {
this.writeEmptyPacket();
} else {
this.stream.flush(true, this.cmd);
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
}
} else {
this.buf = allocateBuffer(remainingLen + 4);
this.pos = 4;
}
}
flushBufferBasic(commandEnd, remainingLen) {
this.buf[0] = this.pos - 4;
this.buf[1] = (this.pos - 4) >>> 8;
this.buf[2] = (this.pos - 4) >>> 16;
this.buf[3] = ++this.cmd.sequenceNo;
this.stream.writeBuf(this.buf.slice(0, this.pos), this.cmd);
if (commandEnd) {
//if last packet fill the max size, must send an empty com to indicate that command end.
if (this.pos === MAX_BUFFER_SIZE) {
this.writeEmptyPacket();
} else {
this.stream.flush(true, this.cmd);
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
}
} else {
this.buf = allocateBuffer(remainingLen + 4);
this.pos = 4;
}
}
writeEmptyPacket() {
const emptyBuf = Buffer.from([0x00, 0x00, 0x00, ++this.cmd.sequenceNo]);
if (this.opts.logPackets || this.opts.debug) {
const packet = Utils.log(this.opts, emptyBuf, 0, 4);
if (this.opts.logPackets) {
this.info.addPacket(
'==> conn:' +
(this.info.threadId ? this.info.threadId : -1) +
' ' +
this.cmd.constructor.name +
'(0,4)\n' +
packet
);
}
if (this.opts.debug) {
console.log(
'==> conn:%d %s\n%s',
this.info.threadId ? this.info.threadId : -1,
this.cmd.constructor.name + '(0,4)',
packet
);
}
}
this.stream.writeBuf(emptyBuf, this.cmd);
this.stream.flush(true, this.cmd);
}
}
function allocateBuffer(len) {
if (len < SMALL_BUFFER_SIZE) {
return Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
} else if (len < MEDIUM_BUFFER_SIZE) {
return Buffer.allocUnsafe(MEDIUM_BUFFER_SIZE);
} else if (len < LARGE_BUFFER_SIZE) {
return Buffer.allocUnsafe(LARGE_BUFFER_SIZE);
} else if (len < BIG_BUFFER_SIZE) {
return Buffer.allocUnsafe(BIG_BUFFER_SIZE);
}
return Buffer.allocUnsafe(MAX_BUFFER_SIZE);
}
module.exports = PacketOutputStream;

509
node_modules/mariadb/lib/io/packet.js generated vendored Normal file
View File

@@ -0,0 +1,509 @@
'use strict';
const Errors = require('../misc/errors');
const Iconv = require('iconv-lite');
const Long = require('long');
const moment = require('moment-timezone');
/**
* Object to easily parse buffer.
*
*/
class Packet {
constructor(buf, pos, end) {
this.buf = buf;
this.pos = pos;
this.end = end;
}
skip(n) {
this.pos += n;
}
readGeometry(dataTypeName) {
const geoBuf = this.readBufferLengthEncoded();
if (geoBuf === null || geoBuf.length === 0) {
if (dataTypeName) {
switch (dataTypeName) {
case 'point':
return { type: 'Point' };
case 'linestring':
return { type: 'LineString' };
case 'polygon':
return { type: 'Polygon' };
case 'multipoint':
return { type: 'MultiPoint' };
case 'multilinestring':
return { type: 'MultiLineString' };
case 'multipolygon':
return { type: 'MultiPolygon' };
default:
return { type: dataTypeName };
}
}
return null;
}
let geoPos = 4;
return readGeometryObject(false);
function parseCoordinates(byteOrder) {
geoPos += 16;
const x = byteOrder ? geoBuf.readDoubleLE(geoPos - 16) : geoBuf.readDoubleBE(geoPos - 16);
const y = byteOrder ? geoBuf.readDoubleLE(geoPos - 8) : geoBuf.readDoubleBE(geoPos - 8);
return [x, y];
}
function readGeometryObject(inner) {
const byteOrder = geoBuf[geoPos++];
const wkbType = byteOrder ? geoBuf.readInt32LE(geoPos) : geoBuf.readInt32BE(geoPos);
geoPos += 4;
switch (wkbType) {
case 1: //wkbPoint
const coords = parseCoordinates(byteOrder);
if (inner) return coords;
return {
type: 'Point',
coordinates: coords
};
case 2: //wkbLineString
const pointNumber = byteOrder ? geoBuf.readInt32LE(geoPos) : geoBuf.readInt32BE(geoPos);
geoPos += 4;
let coordinates = [];
for (let i = 0; i < pointNumber; i++) {
coordinates.push(parseCoordinates(byteOrder));
}
if (inner) return coordinates;
return {
type: 'LineString',
coordinates: coordinates
};
case 3: //wkbPolygon
let polygonCoordinates = [];
const numRings = byteOrder ? geoBuf.readInt32LE(geoPos) : geoBuf.readInt32BE(geoPos);
geoPos += 4;
for (let ring = 0; ring < numRings; ring++) {
const pointNumber = byteOrder ? geoBuf.readInt32LE(geoPos) : geoBuf.readInt32BE(geoPos);
geoPos += 4;
let linesCoordinates = [];
for (let i = 0; i < pointNumber; i++) {
linesCoordinates.push(parseCoordinates(byteOrder));
}
polygonCoordinates.push(linesCoordinates);
}
if (inner) return polygonCoordinates;
return {
type: 'Polygon',
coordinates: polygonCoordinates
};
case 4: //wkbMultiPoint
return {
type: 'MultiPoint',
coordinates: parseGeomArray(byteOrder, true)
};
case 5: //wkbMultiLineString
return {
type: 'MultiLineString',
coordinates: parseGeomArray(byteOrder, true)
};
case 6: //wkbMultiPolygon
return {
type: 'MultiPolygon',
coordinates: parseGeomArray(byteOrder, true)
};
case 7: //wkbGeometryCollection
return {
type: 'GeometryCollection',
geometries: parseGeomArray(byteOrder, false)
};
}
return null;
}
function parseGeomArray(byteOrder, inner) {
let coordinates = [];
const number = byteOrder ? geoBuf.readInt32LE(geoPos) : geoBuf.readInt32BE(geoPos);
geoPos += 4;
for (let i = 0; i < number; i++) {
coordinates.push(readGeometryObject(inner));
}
return coordinates;
}
}
peek() {
return this.buf[this.pos];
}
remaining() {
return this.end - this.pos > 0;
}
readUInt8() {
return this.buf[this.pos++];
}
readUInt16() {
return this.buf[this.pos++] + (this.buf[this.pos++] << 8);
}
readUInt24() {
return this.buf[this.pos++] + (this.buf[this.pos++] << 8) + (this.buf[this.pos++] << 16);
}
readUInt32() {
return (
this.buf[this.pos++] +
(this.buf[this.pos++] << 8) +
(this.buf[this.pos++] << 16) +
this.buf[this.pos++] * 0x1000000
);
}
readInt32() {
return (
this.buf[this.pos++] +
(this.buf[this.pos++] << 8) +
(this.buf[this.pos++] << 16) +
(this.buf[this.pos++] << 24)
);
}
readInt32LE() {
return (
(this.buf[this.pos++] << 24) +
(this.buf[this.pos++] << 16) +
(this.buf[this.pos++] << 8) +
this.buf[this.pos++]
);
}
readInt64() {
// could use readBigInt64LE when support would be 10.20+
const val =
this.buf[this.pos + 4] +
this.buf[this.pos + 5] * 2 ** 8 +
this.buf[this.pos + 6] * 2 ** 16 +
(this.buf[this.pos + 7] << 24);
const vv =
(BigInt(val) << BigInt(32)) +
BigInt(
this.buf[this.pos] +
this.buf[this.pos + 1] * 2 ** 8 +
this.buf[this.pos + 2] * 2 ** 16 +
this.buf[this.pos + 3] * 2 ** 24
);
this.pos += 8;
return vv;
}
readUnsignedLength() {
const type = this.buf[this.pos++] & 0xff;
switch (type) {
case 0xfb:
return null;
case 0xfc:
return this.readUInt16();
case 0xfd:
return this.readUInt24();
case 0xfe:
// limitation to BigInt signed value
return Number(this.readInt64());
default:
return type;
}
}
readBuffer(len) {
this.pos += len;
return this.buf.slice(this.pos - len, this.pos);
}
readBufferRemaining() {
let b = this.buf.slice(this.pos, this.end);
this.pos = this.end;
return b;
}
readBufferLengthEncoded() {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
return this.buf.slice(this.pos - len, this.pos);
}
readStringNullEnded() {
let initialPosition = this.pos;
let cnt = 0;
while (this.remaining() > 0 && this.buf[this.pos++] !== 0) {
cnt++;
}
return this.buf.toString('utf8', initialPosition, initialPosition + cnt);
}
readSignedLength() {
const type = this.buf[this.pos++];
switch (type) {
case 0xfb:
return null;
case 0xfc:
return this.readUInt16();
case 0xfd:
return this.readUInt24();
case 0xfe:
return Number(this.readInt64());
default:
return type;
}
}
readSignedLengthBigInt() {
const type = this.buf[this.pos++];
switch (type) {
case 0xfb:
return null;
case 0xfc:
return BigInt(this.readUInt16());
case 0xfd:
return BigInt(this.readUInt24());
case 0xfe:
return this.readInt64();
default:
return BigInt(type);
}
}
readAsciiStringLengthEncoded() {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
return this.buf.toString('ascii', this.pos - len, this.pos);
}
readStringLengthEncoded(encoding) {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
if (Buffer.isEncoding(encoding)) {
return this.buf.toString(encoding, this.pos - len, this.pos);
}
return Iconv.decode(this.buf.slice(this.pos - len, this.pos), encoding);
}
readLongLengthEncoded(supportBigInt, supportBigNumbers, bigNumberStrings, unsigned) {
const len = this.readUnsignedLength();
if (len === null) return null;
if (supportBigInt) {
const str = this.buf.toString('ascii', this.pos, this.pos + len);
this.pos += len;
return BigInt(str);
}
let result = 0;
let negate = false;
let begin = this.pos;
//minus sign
if (len > 0 && this.buf[begin] === 45) {
negate = true;
begin++;
}
for (; begin < this.pos + len; begin++) {
result = result * 10 + (this.buf[begin] - 48);
}
let val = negate ? -1 * result : result;
this.pos += len;
if (!Number.isSafeInteger(val)) {
const str = this.buf.toString('ascii', this.pos - len, this.pos);
if (bigNumberStrings) return str;
if (supportBigNumbers) {
return Long.fromString(str, unsigned, 10);
}
}
return val;
}
readDecimalLengthEncoded(bigNumberStrings) {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
let str = this.buf.toString('ascii', this.pos - len, this.pos);
return bigNumberStrings ? str : +str;
}
readDate() {
const len = this.readUnsignedLength();
if (len === null) return null;
let res = [];
let value = 0;
let initPos = this.pos;
this.pos += len;
while (initPos < this.pos) {
const char = this.buf[initPos++];
if (char === 45) {
//minus separator
res.push(value);
value = 0;
} else {
value = value * 10 + char - 48;
}
}
res.push(value);
//handle zero-date as null
if (res[0] === 0 && res[1] === 0 && res[2] === 0) return null;
return new Date(res[0], res[1] - 1, res[2]);
}
readDateTime(opts) {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
const str = this.buf.toString('ascii', this.pos - len, this.pos);
if (str.startsWith('0000-00-00 00:00:00')) return null;
if (opts.tz) {
return new Date(
moment.tz(str, opts.tz).clone().tz(opts.localTz).format('YYYY-MM-DD HH:mm:ss.SSSSSS')
);
}
return new Date(str);
}
readIntLengthEncoded() {
const len = this.readUnsignedLength();
if (len === null) return null;
let result = 0;
let negate = false;
let begin = this.pos;
if (len > 0 && this.buf[begin] === 45) {
//minus sign
negate = true;
begin++;
}
for (; begin < this.pos + len; begin++) {
result = result * 10 + (this.buf[begin] - 48);
}
this.pos += len;
return negate ? -1 * result : result;
}
readFloatLengthCoded() {
const len = this.readUnsignedLength();
if (len === null) return null;
this.pos += len;
return +this.buf.toString('ascii', this.pos - len, this.pos);
}
skipLengthCodedNumber() {
const type = this.buf[this.pos++] & 0xff;
switch (type) {
case 251:
return;
case 252:
this.pos +=
2 + (0xffff & ((this.buf[this.pos] & 0xff) + ((this.buf[this.pos + 1] & 0xff) << 8)));
return;
case 253:
this.pos +=
3 +
(0xffffff &
((this.buf[this.pos] & 0xff) +
((this.buf[this.pos + 1] & 0xff) << 8) +
((this.buf[this.pos + 2] & 0xff) << 16)));
return;
case 254:
this.pos +=
8 +
((this.buf[this.pos] & 0xff) +
((this.buf[this.pos + 1] & 0xff) << 8) +
((this.buf[this.pos + 2] & 0xff) << 16) +
((this.buf[this.pos + 3] & 0xff) << 24) +
((this.buf[this.pos + 4] & 0xff) << 32) +
((this.buf[this.pos + 5] & 0xff) << 40) +
((this.buf[this.pos + 6] & 0xff) << 48) +
((this.buf[this.pos + 7] & 0xff) << 56));
return;
default:
this.pos += type;
return;
}
}
positionFromEnd(num) {
this.pos = this.end - num;
}
/**
* For testing purpose only
*/
_toBuf() {
return this.buf.slice(this.pos, this.end);
}
forceOffset(off) {
this.pos = off;
}
length() {
return this.end - this.pos;
}
subPacketLengthEncoded() {
const len = this.readUnsignedLength();
this.skip(len);
return new Packet(this.buf, this.pos - len, this.pos);
}
/**
* Parse ERR_Packet : https://mariadb.com/kb/en/library/err_packet/
*
* @param info current connection info
* @param sql command sql
* @param stack additional stack trace
* @returns {Error}
*/
readError(info, sql, stack) {
this.skip(1);
let errorCode = this.readUInt16();
let sqlState = '';
if (this.peek() === 0x23) {
this.skip(6);
sqlState = this.buf.toString('utf8', this.pos - 5, this.pos);
}
let msg = this.buf.toString('utf8', this.pos, this.end);
if (sql) msg += '\n' + sql;
let fatal = sqlState.startsWith('08') || sqlState === '70100';
if (fatal) {
const packetMsgs = info.getLastPackets();
if (packetMsgs !== '')
return Errors.createError(
msg + '\nlast received packets:\n' + packetMsgs,
fatal,
info,
sqlState,
errorCode,
stack
);
}
return Errors.createError(msg, fatal, info, sqlState, errorCode, stack);
}
}
module.exports = Packet;

481
node_modules/mariadb/lib/io/rewrite-packet.js generated vendored Normal file
View File

@@ -0,0 +1,481 @@
'use strict';
const Iconv = require('iconv-lite');
const QUOTE = 0x27;
const DBL_QUOTE = 0x22;
const ZERO_BYTE = 0x00;
const SLASH = 0x5c;
const SMALL_BUFFER_SIZE = 1024;
const MEDIUM_BUFFER_SIZE = 16384; //16k
const LARGE_BUFFER_SIZE = 131072; //128k
const BIG_BUFFER_SIZE = 1048576; //1M
const MAX_BUFFER_SIZE = 16777219; //16M + 4
const CHARS_GLOBAL_REGEXP = /[\0\"\'\\]/g; // eslint-disable-line no-control-regex
/**
* Packet splitter.
*
* The servers have a limit max_allowed_packet which limits the size of the data sent, to avoid saturating the server in memory.
*
* The following implementation has a workaround that will rewrite the command and separate the send according to this value.
* This implies that this command can send multiple commands, with some tricks for sequencing packets.
*
*/
class ReWritePacket {
constructor(maxAllowedPacket, out, initString, endString) {
this.out = out;
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
this.pos = 4;
this.initStr = initString;
this.endStr = endString;
this.encoding = out.encoding;
this.endStrLength = Buffer.byteLength(this.endStr, this.encoding);
this.waitingResponseNo = 0;
this.singleQuery = false;
this.haveErrorResponse = false;
if (this.encoding === 'utf8') {
this.writeString = this.writeDefaultBufferString;
this.writeStringEscapeQuote = this.writeUtf8StringEscapeQuote;
} else if (Buffer.isEncoding(this.encoding)) {
this.writeString = this.writeDefaultBufferString;
this.writeStringEscapeQuote = this.writeDefaultStringEscapeQuote;
} else {
this.writeString = this.writeDefaultIconvString;
this.writeStringEscapeQuote = this.writeDefaultStringEscapeQuote;
}
this.maxAllowedPacket = maxAllowedPacket;
if (maxAllowedPacket) {
this.maxPacketSize = Math.min(MAX_BUFFER_SIZE, maxAllowedPacket) - this.endStrLength;
} else this.maxPacketSize = 4194304 - this.endStrLength;
this.buf[this.pos++] = 0x03;
this.writeString(this.initStr);
}
growBuffer(len) {
let newCapacity;
if (len + this.pos < MEDIUM_BUFFER_SIZE) {
newCapacity = MEDIUM_BUFFER_SIZE;
} else if (len + this.pos < LARGE_BUFFER_SIZE) {
newCapacity = LARGE_BUFFER_SIZE;
} else if (len + this.pos < BIG_BUFFER_SIZE) {
newCapacity = BIG_BUFFER_SIZE;
} else newCapacity = MAX_BUFFER_SIZE;
if (newCapacity > this.maxPacketSize && this.markPos) {
this.flush(false, len);
return true;
}
let newBuf = Buffer.allocUnsafe(Math.min(newCapacity));
this.buf.copy(newBuf, 0, 0, this.pos);
this.buf = newBuf;
return false;
}
writeInt8(value) {
let flushed = false;
if (this.pos + 1 + this.endStrLength >= this.buf.length) {
if (this.buf.length < MAX_BUFFER_SIZE) {
flushed = this.growBuffer(1);
} else {
this.flush(false, 1);
this.buf[this.pos++] = value;
return true;
}
}
this.buf[this.pos++] = value;
return flushed;
}
/**
* Write ascii string to socket (no escaping)
*
* @param str string
*/
writeStringAscii(str) {
let len = str.length;
//not enough space remaining
if (len >= this.buf.length - (this.pos + this.endStrLength)) {
let strBuf = Buffer.from(str, 'ascii');
return this.writeBuffer(strBuf, 0, strBuf.length);
}
for (let off = 0; off < len; ) {
this.buf[this.pos++] = str.charCodeAt(off++);
}
return false;
}
writeUtf8StringEscapeQuote(str) {
const charsLength = str.length;
//not enough space remaining
if (charsLength * 3 + 2 >= this.buf.length - (this.pos + this.endStrLength)) {
let flushed;
const arr = Buffer.from(str, 'utf8');
flushed = this.writeInt8(QUOTE);
flushed = this.writeBufferEscape(arr) || flushed;
flushed = this.writeInt8(QUOTE) || flushed;
return flushed;
}
//create UTF-8 byte array
//since javascript char are internally using UTF-16 using surrogate's pattern, 4 bytes unicode characters will
//represent 2 characters : example "\uD83C\uDFA4" = 🎤 unicode 8 "no microphones"
//so max size is 3 * charLength
//(escape characters are 1 byte encoded, so length might only be 2 when escaped)
// + 2 for the quotes for text protocol
let charsOffset = 0;
let currChar;
this.buf[this.pos++] = QUOTE;
//quick loop if only ASCII chars for faster escape
for (
;
charsOffset < charsLength && (currChar = str.charCodeAt(charsOffset)) < 0x80;
charsOffset++
) {
if (
currChar === SLASH ||
currChar === QUOTE ||
currChar === ZERO_BYTE ||
currChar === DBL_QUOTE
) {
this.buf[this.pos++] = SLASH;
}
this.buf[this.pos++] = currChar;
}
//if quick loop not finished
while (charsOffset < charsLength) {
currChar = str.charCodeAt(charsOffset++);
if (currChar < 0x80) {
if (
currChar === SLASH ||
currChar === QUOTE ||
currChar === ZERO_BYTE ||
currChar === DBL_QUOTE
) {
this.buf[this.pos++] = SLASH;
}
this.buf[this.pos++] = currChar;
} else if (currChar < 0x800) {
this.buf[this.pos++] = 0xc0 | (currChar >> 6);
this.buf[this.pos++] = 0x80 | (currChar & 0x3f);
} else if (currChar >= 0xd800 && currChar < 0xe000) {
//reserved for surrogate - see https://en.wikipedia.org/wiki/UTF-16
if (currChar < 0xdc00) {
//is high surrogate
if (charsOffset + 1 > charsLength) {
this.buf[this.pos++] = 0x3f;
} else {
const nextChar = str.charCodeAt(charsOffset);
if (nextChar >= 0xdc00 && nextChar < 0xe000) {
//is low surrogate
const surrogatePairs =
(currChar << 10) + nextChar + (0x010000 - (0xd800 << 10) - 0xdc00);
this.buf[this.pos++] = 0xf0 | (surrogatePairs >> 18);
this.buf[this.pos++] = 0x80 | ((surrogatePairs >> 12) & 0x3f);
this.buf[this.pos++] = 0x80 | ((surrogatePairs >> 6) & 0x3f);
this.buf[this.pos++] = 0x80 | (surrogatePairs & 0x3f);
charsOffset++;
} else {
//must have low surrogate
this.buf[this.pos++] = 0x3f;
}
}
} else {
//low surrogate without high surrogate before
this.buf[this.pos++] = 0x3f;
}
} else {
this.buf[this.pos++] = 0xe0 | (currChar >> 12);
this.buf[this.pos++] = 0x80 | ((currChar >> 6) & 0x3f);
this.buf[this.pos++] = 0x80 | (currChar & 0x3f);
}
}
this.buf[this.pos++] = QUOTE;
return false;
}
writeDefaultIconvString(str) {
let buf = Iconv.encode(str, this.encoding);
return this.writeBuffer(buf, 0, buf.length);
}
writeDefaultBufferString(str) {
//javascript use UCS-2 or UTF-16 string internal representation
//that means that string to byte will be a maximum of * 3
// (4 bytes utf-8 are represented on 2 UTF-16 characters)
if (str.length * 3 < this.buf.length - (this.pos + this.endStrLength)) {
this.pos += this.buf.write(str, this.pos, this.encoding);
return false;
}
//checking real length
let flushed = false;
let byteLength = Buffer.byteLength(str, this.encoding);
if (byteLength > this.buf.length - (this.pos + this.endStrLength)) {
if (this.buf.length < MAX_BUFFER_SIZE) {
flushed = this.growBuffer(byteLength);
}
if (byteLength > this.buf.length - (this.pos + this.endStrLength)) {
//not enough space in buffer, will stream :
let strBuf = Buffer.from(str, this.encoding);
flushed = this.writeBuffer(strBuf, 0, strBuf.length) || flushed;
return flushed;
}
}
this.pos += this.buf.write(str, this.pos, this.encoding);
return flushed;
}
/**
* Parameters need to be properly escaped :
* following characters are to be escaped by "\" :
* - \0
* - \\
* - \'
* - \"
* regex split part of string writing part, and escaping special char.
* Those chars are <= 7f meaning that this will work even with multi-byte encoding
*
* @param str string to escape.
*/
writeDefaultStringEscapeQuote(str) {
let flushed = this.writeInt8(QUOTE);
let match;
let lastIndex = 0;
while ((match = CHARS_GLOBAL_REGEXP.exec(str)) !== null) {
flushed = this.writeString(str.slice(lastIndex, match.index)) || flushed;
flushed = this.writeInt8(SLASH) || flushed;
flushed = this.writeInt8(match[0].charCodeAt(0)) || flushed;
lastIndex = CHARS_GLOBAL_REGEXP.lastIndex;
}
if (lastIndex === 0) {
// Nothing was escaped
flushed = this.writeString(str) || flushed;
flushed = this.writeInt8(QUOTE) || flushed;
return flushed;
}
if (lastIndex < str.length) {
flushed = this.writeString(str.slice(lastIndex)) || flushed;
}
flushed = this.writeInt8(QUOTE) || flushed;
return flushed;
}
writeBufferEscape(val) {
let flushed = false;
let valLen = val.length;
if (valLen * 2 > this.buf.length - (this.pos + this.endStrLength)) {
//makes buffer bigger (up to 16M)
if (this.buf.length < MAX_BUFFER_SIZE) flushed = this.growBuffer(valLen * 2);
//data may still be bigger than buffer.
//must flush buffer when full (and reset position to 4)
if (valLen * 2 > this.buf.length - (this.pos + this.endStrLength)) {
//not enough space in buffer, will fill buffer
for (let i = 0; i < valLen; i++) {
switch (val[i]) {
case QUOTE:
case SLASH:
case DBL_QUOTE:
case ZERO_BYTE:
if (this.pos >= this.buf.length) this.flush(false, (valLen - i) * 2);
this.buf[this.pos++] = SLASH; //add escape slash
}
if (this.pos >= this.buf.length) this.flush(false, (valLen - i) * 2);
this.buf[this.pos++] = val[i];
}
return true;
}
}
//sure to have enough place to use buffer directly
for (let i = 0; i < valLen; i++) {
switch (val[i]) {
case QUOTE:
case SLASH:
case DBL_QUOTE:
case ZERO_BYTE:
this.buf[this.pos++] = SLASH; //add escape slash
}
this.buf[this.pos++] = val[i];
}
return flushed;
}
writeBuffer(arr, off, len) {
let flushed = false;
if (len > this.buf.length - (this.pos + this.endStrLength)) {
if (this.buf.length < MAX_BUFFER_SIZE) flushed = this.growBuffer(len);
//max buffer size
if (len > this.buf.length - (this.pos + this.endStrLength)) {
//not enough space in buffer, will stream :
// fill buffer and flush until all data are snd
let remainingLen = len;
while (true) {
//filling buffer
let lenToFillBuffer = Math.min(MAX_BUFFER_SIZE - this.pos, remainingLen);
arr.copy(this.buf, this.pos, off, off + lenToFillBuffer);
remainingLen -= lenToFillBuffer;
off += lenToFillBuffer;
this.pos += lenToFillBuffer;
if (remainingLen === 0) return flushed;
this.flush(false, remainingLen);
flushed = true;
}
}
}
arr.copy(this.buf, this.pos, off, off + len);
this.pos += len;
return flushed;
}
mark(isLast) {
let flushed = false;
if (this.singleQuery) {
//end of big query that is more than 16M
//write single one
flushed = this.writeString(this.endStr);
if (!this.haveErrorResponse) {
const packetSendSize =
this.pos +
(this.singleQuerySequenceNo != undefined
? (this.singleQuerySequenceNo + 1) * MAX_BUFFER_SIZE
: 0);
if (this.maxAllowedPacket && packetSendSize > this.maxAllowedPacket) {
console.log(
"will send a packet to db server with size > connection option 'maxAllowedPacket' (size send is " +
packetSendSize +
') connection might be reset by server'
);
}
this.copyAndFlush(true);
flushed = true;
this.markPos = undefined;
}
this.singleQuerySequenceNo = undefined;
this.singleQueryCompressSequenceNo = undefined;
this.singleQuery = false;
this.buf[this.pos++] = 0x03;
this.writeString(this.initStr);
this.markPos = undefined;
} else {
if (this.markPos && this.pos + this.endStrLength > this.maxPacketSize) {
//not enough room for current query, flush mark.
this.flushMark();
flushed = true;
}
//just mark ending query
this.markPos = this.pos;
if (isLast) {
this.flushMark();
flushed = true;
}
if (!isLast) flushed = this.writeStringAscii(',') || flushed;
}
return flushed;
}
flush(end, remainingLen) {
if (this.markPos && !this.singleQuery) {
this.flushMark();
} else {
//one insert is more than 16M, will continue to mono insert, hoping
//that max_allowed_packet is sized accordingly to query.
if (this.buf.length < MAX_BUFFER_SIZE) {
//in this case, connector has default to 4M packet, and a single query size
//is > to 4mb. growing buffer to 16M
let newBuf = Buffer.allocUnsafe(MAX_BUFFER_SIZE);
this.buf.copy(newBuf, 0, 0, this.pos);
this.buf = newBuf;
} else {
if (!this.haveErrorResponse) {
if (this.maxAllowedPacket && this.buf.length > this.maxAllowedPacket) {
console.log(
"will send a packet to server with size > connection option 'maxAllowedPacket' (size send is " +
this.pos +
') connection might be reset by server'
);
}
this.copyAndFlush(false);
this.markPos = undefined;
if (!this.singleQuery) this.waitingResponseNo++;
this.singleQuery = true;
this.singleQuerySequenceNo = this.out.cmd.sequenceNo;
this.singleQueryCompressSequenceNo = this.out.cmd.compressSequenceNo;
}
}
}
}
flushMark() {
let afterMark;
if (this.pos !== this.markPos) {
//remove "," character
afterMark = Buffer.allocUnsafe(this.pos - this.markPos - 1);
this.buf.copy(afterMark, 0, this.markPos + 1, this.pos);
}
this.pos = this.markPos;
this.writeString(this.endStr);
if (!this.haveErrorResponse) {
this.copyAndFlush(true);
this.waitingResponseNo++;
}
this.pos = 4;
this.buf[this.pos++] = 0x03;
this.writeString(this.initStr);
this.markPos = undefined;
if (afterMark) {
if (this.buf.length - this.pos < afterMark.length)
this.growBuffer(afterMark.length - (this.buf.length - this.pos));
afterMark.copy(this.buf, this.pos, 0, afterMark.length);
this.pos += afterMark.length;
}
this.singleQuery = false;
this.singleQuerySequenceNo = undefined;
this.singleQueryCompressSequenceNo = undefined;
}
copyAndFlush(ended) {
this.out.buf = this.buf;
this.out.pos = this.pos;
if (this.singleQuerySequenceNo != undefined) {
this.out.cmd.sequenceNo = this.singleQuerySequenceNo;
this.out.cmd.compressSequenceNo = this.singleQueryCompressSequenceNo;
} else {
this.out.cmd.sequenceNo = -1;
this.out.cmd.compressSequenceNo = -1;
}
this.out.flushBuffer(ended);
if (this.singleQuerySequenceNo != undefined) {
this.singleQuerySequenceNo = this.out.cmd.sequenceNo;
this.singleQueryCompressSequenceNo = this.out.cmd.compressSequenceNo;
}
this.pos = 4;
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE);
}
endedWithError() {
this.haveErrorResponse = true;
}
}
module.exports = ReWritePacket;

View File

@@ -0,0 +1,96 @@
'use strict';
const Queue = require('denque');
const _addPacket = function (msg) {
this.lastPackets.push(msg);
while (this.lastPackets.size() > 32) this.lastPackets.shift();
};
const _getLastPackets = function () {
let output = '';
let packet;
while ((packet = this.lastPackets.shift())) {
output += '\n' + packet;
}
return output;
};
class ConnectionInformation {
constructor() {
this.threadId = -1;
this.status = null;
this.serverVersion = null;
this.serverCapabilities = null;
}
addPacket(msg) {}
getLastPackets() {
return '';
}
enableLogPacket() {
this.lastPackets = new Queue();
this.addPacket = _addPacket.bind(this);
this.getLastPackets = _getLastPackets.bind(this);
}
hasMinVersion(major, minor, patch) {
if (!this.serverVersion)
throw new Error('cannot know if server version until connection is established');
if (!major) throw new Error('a major version must be set');
if (!minor) minor = 0;
if (!patch) patch = 0;
let ver = this.serverVersion;
return (
ver.major > major ||
(ver.major === major && ver.minor > minor) ||
(ver.major === major && ver.minor === minor && ver.patch >= patch)
);
}
isMariaDB() {
if (!this.serverVersion)
throw new Error('cannot know if server is MariaDB until connection is established');
return this.serverVersion.mariaDb;
}
/**
* Parse raw info to set server major/minor/patch values
* @param info
*/
static parseVersionString(info) {
let car;
let offset = 0;
let type = 0;
let val = 0;
for (; offset < info.serverVersion.raw.length; offset++) {
car = info.serverVersion.raw.charCodeAt(offset);
if (car < 48 || car > 57) {
switch (type) {
case 0:
info.serverVersion.major = val;
break;
case 1:
info.serverVersion.minor = val;
break;
case 2:
info.serverVersion.patch = val;
return;
}
type++;
val = 0;
} else {
val = val * 10 + car - 48;
}
}
//serverVersion finished by number like "5.5.57", assign patchVersion
if (type === 2) info.serverVersion.patch = val;
}
}
module.exports = ConnectionInformation;

116
node_modules/mariadb/lib/misc/errors.js generated vendored Normal file
View File

@@ -0,0 +1,116 @@
'use strict';
const ErrorCodes = require('../const/error-code');
class SqlError extends Error {
constructor(msg, fatal, info, sqlState, errno, additionalStack, addHeader) {
super(
(addHeader === undefined || addHeader
? '(conn=' +
(info ? (info.threadId ? info.threadId : -1) : -1) +
', no: ' +
(errno ? errno : -1) +
', SQLState: ' +
(sqlState ? sqlState : 'HY000') +
') '
: '') + msg
);
this.fatal = fatal;
this.errno = errno;
this.sqlState = sqlState;
if (errno > 45000 && errno < 46000) {
//driver error
this.code = errByNo[errno] || 'UNKNOWN';
} else {
this.code = ErrorCodes.codes[this.errno] || 'UNKNOWN';
}
if (additionalStack) {
//adding caller stack, removing initial "Error:\n"
this.stack +=
'\n From event:\n' + additionalStack.substring(additionalStack.indexOf('\n') + 1);
}
}
}
/**
* Error factory, so error get connection information.
*
* @param msg current error message
* @param fatal is error fatal
* @param info connection information
* @param sqlState sql state
* @param errno error number
* @param additionalStack additional stack trace to see
* @param addHeader add connection information
* @returns {Error} the error
*/
module.exports.createError = function (
msg,
fatal,
info,
sqlState,
errno,
additionalStack,
addHeader
) {
return new SqlError(msg, fatal, info, sqlState, errno, additionalStack, addHeader);
};
/********************************************************************************
* Driver specific errors
********************************************************************************/
module.exports.ER_CONNECTION_ALREADY_CLOSED = 45001;
module.exports.ER_ALREADY_CONNECTING = 45002;
module.exports.ER_MYSQL_CHANGE_USER_BUG = 45003;
module.exports.ER_CMD_NOT_EXECUTED_DESTROYED = 45004;
module.exports.ER_NULL_CHAR_ESCAPEID = 45005;
module.exports.ER_NULL_ESCAPEID = 45006;
module.exports.ER_NOT_IMPLEMENTED_FORMAT = 45007;
module.exports.ER_NODE_NOT_SUPPORTED_TLS = 45008;
module.exports.ER_SOCKET_UNEXPECTED_CLOSE = 45009;
module.exports.ER_UNEXPECTED_PACKET = 45011;
module.exports.ER_CONNECTION_TIMEOUT = 45012;
module.exports.ER_CMD_CONNECTION_CLOSED = 45013;
module.exports.ER_CHANGE_USER_BAD_PACKET = 45014;
module.exports.ER_PING_BAD_PACKET = 45015;
module.exports.ER_MISSING_PARAMETER = 45016;
module.exports.ER_PARAMETER_UNDEFINED = 45017;
module.exports.ER_PLACEHOLDER_UNDEFINED = 45018;
module.exports.ER_SOCKET = 45019;
module.exports.ER_EOF_EXPECTED = 45020;
module.exports.ER_LOCAL_INFILE_DISABLED = 45021;
module.exports.ER_LOCAL_INFILE_NOT_READABLE = 45022;
module.exports.ER_SERVER_SSL_DISABLED = 45023;
module.exports.ER_AUTHENTICATION_BAD_PACKET = 45024;
module.exports.ER_AUTHENTICATION_PLUGIN_NOT_SUPPORTED = 45025;
module.exports.ER_SOCKET_TIMEOUT = 45026;
module.exports.ER_POOL_ALREADY_CLOSED = 45027;
module.exports.ER_GET_CONNECTION_TIMEOUT = 45028;
module.exports.ER_SETTING_SESSION_ERROR = 45029;
module.exports.ER_INITIAL_SQL_ERROR = 45030;
module.exports.ER_BATCH_WITH_NO_VALUES = 45031;
module.exports.ER_RESET_BAD_PACKET = 45032;
module.exports.ER_WRONG_IANA_TIMEZONE = 45033;
module.exports.ER_LOCAL_INFILE_WRONG_FILENAME = 45034;
module.exports.ER_ADD_CONNECTION_CLOSED_POOL = 45035;
module.exports.ER_WRONG_AUTO_TIMEZONE = 45036;
module.exports.ER_CLOSING_POOL = 45037;
module.exports.ER_TIMEOUT_NOT_SUPPORTED = 45038;
module.exports.ER_INITIAL_TIMEOUT_ERROR = 45039;
module.exports.ER_DUPLICATE_FIELD = 45040;
module.exports.ER_CLIENT_OPTION_INCOMPATIBILITY = 45041;
module.exports.ER_PING_TIMEOUT = 45042;
module.exports.ER_BAD_PARAMETER_VALUE = 45043;
module.exports.ER_CANNOT_RETRIEVE_RSA_KEY = 45044;
module.exports.ER_MINIMUM_NODE_VERSION_REQUIRED = 45045;
const keys = Object.keys(module.exports);
const errByNo = {};
for (let i = 0; i < keys.length; i++) {
const keyName = keys[i];
if (keyName !== 'createError') {
errByNo[module.exports[keyName]] = keyName;
}
}
module.exports.SqlError = SqlError;

1025
node_modules/mariadb/lib/misc/parse.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

294
node_modules/mariadb/lib/misc/utils.js generated vendored Normal file
View File

@@ -0,0 +1,294 @@
'use strict';
const Long = require('long');
const hexArray = '0123456789ABCDEF'.split('');
const Errors = require('../misc/errors');
const CommonText = require('../cmd/common-text-cmd');
const Iconv = require('iconv-lite');
/**
* Write bytes/hexadecimal value of a byte array to a string.
* String output example :
* 38 00 00 00 03 63 72 65 61 74 65 20 74 61 62 6C 8....create tabl
* 65 20 42 6C 6F 62 54 65 73 74 63 6C 6F 62 74 65 e BlobTestclobte
* 73 74 32 20 28 73 74 72 6D 20 74 65 78 74 29 20 st2 (strm text)
* 43 48 41 52 53 45 54 20 75 74 66 38 CHARSET utf8
*/
module.exports.log = function (opts, buf, off, end, header) {
let out = [];
if (!buf) return '';
if (off === undefined || off === null) off = 0;
if (end === undefined || end === null) end = buf.length;
let asciiValue = new Array(16);
asciiValue[8] = ' ';
let useHeader = header !== undefined;
let offset = off || 0;
const maxLgh = Math.min(useHeader ? opts.debugLen - header.length : opts.debugLen, end - offset);
const isLimited = end - offset > maxLgh;
let byteValue;
let posHexa = 0;
let pos = 0;
out.push(
'+--------------------------------------------------+\n' +
'| 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n' +
'+--------------------------------------------------+------------------+\n'
);
if (useHeader) {
while (pos < header.length) {
if (posHexa === 0) out.push('| ');
byteValue = header[pos++] & 0xff;
out.push(hexArray[byteValue >>> 4], hexArray[byteValue & 0x0f], ' ');
asciiValue[posHexa++] =
byteValue > 31 && byteValue < 127 ? String.fromCharCode(byteValue) : '.';
if (posHexa === 8) out.push(' ');
}
}
pos = offset;
while (pos < maxLgh + offset) {
if (posHexa === 0) out.push('| ');
byteValue = buf[pos] & 0xff;
out.push(hexArray[byteValue >>> 4], hexArray[byteValue & 0x0f], ' ');
asciiValue[posHexa++] =
byteValue > 31 && byteValue < 127 ? String.fromCharCode(byteValue) : '.';
if (posHexa === 8) out.push(' ');
if (posHexa === 16) {
out.push('| ', asciiValue.join(''), ' |\n');
posHexa = 0;
}
pos++;
}
let remaining = posHexa;
if (remaining > 0) {
if (remaining < 8) {
for (; remaining < 8; remaining++) {
out.push(' ');
asciiValue[posHexa++] = ' ';
}
out.push(' ');
}
for (; remaining < 16; remaining++) {
out.push(' ');
asciiValue[posHexa++] = ' ';
}
out.push('| ', asciiValue.join(''), isLimited ? ' |...\n' : ' |\n');
} else if (isLimited) {
out[out.length - 1] = ' |...\n';
}
out.push('+--------------------------------------------------+------------------+\n');
return out.join('');
};
module.exports.escapeId = (opts, info, value) => {
if (!value || value === '') {
throw Errors.createError(
'Cannot escape empty ID value',
false,
info,
'0A000',
Errors.ER_NULL_ESCAPEID
);
}
if (value.includes('\u0000')) {
throw Errors.createError(
'Cannot escape ID with null character (u0000)',
false,
info,
'0A000',
Errors.ER_NULL_CHAR_ESCAPEID
);
}
// always return escaped value, event when there is no special characters
// to permit working with reserved words
if (value.match(/^`.+`$/g)) {
// already escaped
return value;
}
return '`' + value.replace(/`/g, '``') + '`';
};
module.exports.escape = (opts, info, value) => {
if (value === undefined || value === null) return 'NULL';
switch (typeof value) {
case 'boolean':
return value ? 'true' : 'false';
case 'bigint':
case 'number':
return '' + value;
case 'object':
if (Object.prototype.toString.call(value) === '[object Date]') {
return opts.tz
? opts.tz === 'Etc/UTC'
? CommonText.getUtcDate(value, opts)
: CommonText.getTimezoneDate(value, opts)
: CommonText.getLocalDate(value, opts);
} else if (Buffer.isBuffer(value)) {
let stValue;
if (Buffer.isEncoding(opts.collation.charset)) {
stValue = value.toString(opts.collation.charset, 0, value.length);
} else {
stValue = Iconv.decode(value, opts.collation.charset);
}
return "_binary'" + escapeString(stValue) + "'";
} else if (typeof value.toSqlString === 'function') {
return "'" + escapeString(String(value.toSqlString())) + "'";
} else if (Long.isLong(value)) {
return value.toString();
} else if (Array.isArray(value)) {
let out = opts.arrayParenthesis ? '(' : '';
for (let i = 0; i < value.length; i++) {
if (i !== 0) out += ',';
out += this.escape(opts, info, value[i]);
}
if (opts.arrayParenthesis) out += ')';
return out;
} else {
if (
value.type != null &&
[
'Point',
'LineString',
'Polygon',
'MultiPoint',
'MultiLineString',
'MultiPolygon',
'GeometryCollection'
].includes(value.type)
) {
//GeoJSON format.
let prefix =
info &&
((info.isMariaDB() && info.hasMinVersion(10, 1, 4)) ||
(!info.isMariaDB() && info.hasMinVersion(5, 7, 6)))
? 'ST_'
: '';
switch (value.type) {
case 'Point':
return (
prefix +
"PointFromText('POINT(" +
CommonText.geoPointToString(value.coordinates) +
")')"
);
case 'LineString':
return (
prefix +
"LineFromText('LINESTRING(" +
CommonText.geoArrayPointToString(value.coordinates) +
")')"
);
case 'Polygon':
return (
prefix +
"PolygonFromText('POLYGON(" +
CommonText.geoMultiArrayPointToString(value.coordinates) +
")')"
);
case 'MultiPoint':
return (
prefix +
"MULTIPOINTFROMTEXT('MULTIPOINT(" +
CommonText.geoArrayPointToString(value.coordinates) +
")')"
);
case 'MultiLineString':
return (
prefix +
"MLineFromText('MULTILINESTRING(" +
CommonText.geoMultiArrayPointToString(value.coordinates) +
")')"
);
case 'MultiPolygon':
return (
prefix +
"MPolyFromText('MULTIPOLYGON(" +
CommonText.geoMultiPolygonToString(value.coordinates) +
")')"
);
case 'GeometryCollection':
return (
prefix +
"GeomCollFromText('GEOMETRYCOLLECTION(" +
CommonText.geometricCollectionToString(value.geometries) +
")')"
);
}
} else {
if (opts.permitSetMultiParamEntries) {
let out = '';
let first = true;
for (let key in value) {
const val = value[key];
if (typeof val === 'function') continue;
if (first) {
first = false;
} else {
out += ',';
}
out += '`' + key + '`=';
out += this.escape(opts, info, val);
}
if (out === '') return "'" + escapeString(JSON.stringify(value)) + "'";
return out;
} else {
return "'" + escapeString(JSON.stringify(value)) + "'";
}
}
}
default:
return "'" + escapeString(value) + "'";
}
};
// see https://mariadb.com/kb/en/library/string-literals/
const LITTERAL_ESCAPE = {
'\u0000': '\\0',
"'": "\\'",
'"': '\\"',
'\b': '\\b',
'\n': '\\n',
'\r': '\\r',
'\t': '\\t',
'\u001A': '\\Z',
'\\': '\\\\'
};
const escapeString = (val) => {
const pattern = /[\u0000'"\b\n\r\t\u001A\\]/g;
let offset = 0;
let escaped = '';
let match;
while ((match = pattern.exec(val))) {
escaped += val.substring(offset, match.index);
escaped += LITTERAL_ESCAPE[match[0]];
offset = pattern.lastIndex;
}
if (offset === 0) {
return val;
}
if (offset < val.length) {
escaped += val.substring(offset);
}
return escaped;
};

590
node_modules/mariadb/lib/pool-base.js generated vendored Normal file
View File

@@ -0,0 +1,590 @@
'use strict';
const EventEmitter = require('events');
const util = require('util');
const Queue = require('denque');
const Errors = require('./misc/errors');
const Utils = require('./misc/utils');
function PoolBase(options, processTask, createConnectionPool, pingPromise) {
//*****************************************************************
// public methods
//*****************************************************************
/**
* Retrieve a connection from pool.
* Create a new one, if limit is not reached.
* wait until acquireTimeout.
*
* @return {Promise}
*/
this.getConnection = function () {
return addRequest(this);
};
/**
* Execute a query on one connection from pool.
*
* @param sql sql command
* @param value parameter value of sql command (not mandatory)
* @return {Promise}
*/
this.query = function (sql, value) {
return addRequest(this, sql, value, false);
};
/**
* Execute a batch on one connection from pool.
*
* @param sql sql command
* @param value parameter value of sql command (not mandatory)
* @return {Promise}
*/
this.batch = function (sql, value) {
return addRequest(this, sql, value, true);
};
/**
* Close all connection in pool
*
* @return Promise
*/
this.end = function () {
if (closed) {
return Promise.reject(
Errors.createError(
'pool is already closed',
false,
null,
'HY000',
Errors.ER_POOL_ALREADY_CLOSED,
undefined,
false
)
);
}
closed = true;
clearInterval(idleMaintainingTask);
//close unused connections
const idleConnectionsEndings = [];
let conn;
while ((conn = idleConnections.shift())) {
idleConnectionsEndings.push(conn.forceEnd());
}
firstTaskTimeout = clearTimeout(firstTaskTimeout);
//reject all waiting task
if (taskQueue.size() > 0) {
let task;
const err = Errors.createError(
'pool is ending, connection request aborted',
false,
null,
'HY000',
Errors.ER_CLOSING_POOL,
undefined,
false
);
while ((task = taskQueue.shift())) {
process.nextTick(task.reject, err);
}
}
return Promise.all(idleConnectionsEndings);
};
/**
* Get current active connections.
* @return {number}
*/
this.activeConnections = function () {
return Object.keys(activeConnections).length;
};
/**
* Get current total connection number.
* @return {number}
*/
this.totalConnections = function () {
return this.activeConnections() + this.idleConnections();
};
/**
* Get current idle connection number.
* @return {number}
*/
this.idleConnections = function () {
return idleConnections.size();
};
/**
* Get current stacked connection request.
* @return {number}
*/
this.taskQueueSize = function () {
return taskQueue.size();
};
/**
* First connection creation.
* activation is slightly different than pooling grow : If connection fails, there is many retries for 30s
* (option initializationTimeout).
* If connection fails, error will be thrown to request / console if no request, to ensure that error is thrown.
*/
this.initialize = function () {
connectionInCreation = true;
const self = this;
const timeoutEnd = Date.now() + opts.initializationTimeout;
connectionCreationLoop(self, 0, timeoutEnd)
.then((conn) => {
//add to pool
if (closed) {
conn.forceEnd().catch((err) => {});
} else {
addPoolConnection(self, conn);
if (opts.idleTimeout > 0) {
idleMaintainingTask = setInterval(idleMaintainer, 500, self);
}
}
})
.catch((err) => {
connectionInCreation = false;
const task = taskQueue.shift();
if (task) {
firstTaskTimeout = clearTimeout(firstTaskTimeout);
process.nextTick(task.reject, err);
resetTimeoutToNextTask();
} else if (!closed) {
console.error(err);
}
})
.finally(() => {
ensurePoolSize(self);
});
};
this.escape = (value) => {
return Utils.escape(options.connOptions, searchInfo(), value);
};
this.escapeId = (value) => {
return Utils.escapeId(options.connOptions, searchInfo(), value);
};
//*****************************************************************
// internal methods
//*****************************************************************
/**
* Search info object of an existing connection. to know server type and version.
* @returns information object if connection available.
*/
const searchInfo = () => {
let info = null;
let conn = idleConnections.get(0);
if (conn == null) {
conn = Object.keys(activeConnections)[0];
}
if (conn != null) {
info = conn.info;
}
return info;
};
/**
* Get a connection from pool / execute query
*
* @param pool current pool
* @param sql sql value (not mandatory)
* @param values sql parameter (not mandatory)
* @param isBatch is batch request
* @return {*}
*/
const addRequest = function (pool, sql, values, isBatch) {
if (closed) {
return Promise.reject(
Errors.createError(
'pool is closed',
false,
null,
'HY000',
Errors.ER_POOL_ALREADY_CLOSED,
undefined,
false
)
);
}
return getIdleValidConnection(pool).then(
(conn) => {
pool.emit('acquire', conn);
return processTask(conn, sql, values, isBatch);
},
() => {
process.nextTick(() => pool.emit('enqueue'));
//no idle connection available
//create a new connection if limit is not reached
ensurePoolSize(pool);
//connections are all used, stack demand.
return new Promise((resolve, reject) => {
const task = {
timeout: Date.now() + opts.acquireTimeout,
reject: reject,
resolve: resolve,
sql: sql,
values: values,
isBatch: isBatch
};
if (!firstTaskTimeout) {
firstTaskTimeout = setTimeout(rejectAndResetTimeout, opts.acquireTimeout, task);
}
taskQueue.push(task);
});
}
);
};
/**
* Return an idle Connection.
* If connection has not been used for some time ( minDelayValidation), validate connection status.
*
* @param pool pool
* @returns {Promise<Connection|null>)} connection of null of no valid idle connection.
*/
const getIdleValidConnection = function (pool) {
if (idleConnections.isEmpty()) {
return Promise.reject(null);
}
const conn = idleConnections.shift();
activeConnections[conn.threadId] = conn;
if (opts.minDelayValidation <= 0 || Date.now() - conn.lastUse > opts.minDelayValidation) {
return pingPromise(conn)
.then(() => {
initLeakProcess(conn);
return Promise.resolve(conn);
})
.catch((err) => {
delete activeConnections[conn.threadId];
pool.emit('_remove-conn');
return getIdleValidConnection(pool);
});
} else {
//just check connection state
if (conn.isValid()) {
initLeakProcess(conn);
return Promise.resolve(conn);
} else {
delete activeConnections[conn.threadId];
pool.emit('_remove-conn');
return getIdleValidConnection(pool);
}
}
};
/**
* Task request timeout handler
* @param task
*/
const timeoutTask = (task) => {
firstTaskTimeout = null;
if (task === taskQueue.peekFront()) {
taskQueue.shift();
process.nextTick(
task.reject,
Errors.createError(
'retrieve connection from pool timeout after ' +
Math.abs(Date.now() - (task.timeout - opts.acquireTimeout)) +
'ms',
false,
null,
'HY000',
Errors.ER_GET_CONNECTION_TIMEOUT,
undefined,
false
)
);
} else {
throw new Error('Rejection by timeout without task !!!');
}
};
/**
* Reject task, and reset timeout to next waiting task if any.
* @param task
*/
const rejectAndResetTimeout = (task) => {
timeoutTask(task);
resetTimeoutToNextTask();
};
/**
* Loop for connection creation.
* This permits to wait before next try after a connection fail.
*
* @param pool current pool
* @param iteration current iteration
* @param timeoutEnd ending timeout
* @returns {Promise<any>} Connection if found, error if not
*/
const connectionCreationLoop = function (pool, iteration, timeoutEnd) {
return new Promise(function (resolve, reject) {
const creationTryout = function (resolve, reject) {
if (closed) {
reject(
Errors.createError(
'Cannot create new connection to pool, pool closed',
true,
null,
'08S01',
Errors.ER_ADD_CONNECTION_CLOSED_POOL,
null
)
);
return;
}
iteration++;
createConnectionPool(pool)
.then((conn) => {
resolve(conn);
})
.catch((err) => {
//if timeout is reached or authentication fail return error
if (
closed ||
(err.errno && (err.errno === 1524 || err.errno === 1045 || err.errno === 1698)) ||
timeoutEnd < Date.now()
) {
reject(err);
return;
}
setTimeout(creationTryout.bind(null, resolve, reject), 500);
});
};
//initial without timeout
creationTryout(resolve, reject);
});
};
const addPoolConnection = function (pool, conn) {
conn.lastUse = Date.now();
const initialDestroyFct = conn.destroy;
conn.destroy = () => {
removeLeakProcess(conn);
delete activeConnections[conn.threadId];
initialDestroyFct();
pool.emit('_remove-conn');
};
//Connection error
// -> evict connection from pool
conn.on('error', (err) => {
let idx = 0;
let currConn;
removeLeakProcess(conn);
delete activeConnections[conn.threadId];
while ((currConn = idleConnections.peekAt(idx))) {
if (currConn === conn) {
idleConnections.removeOne(idx);
break;
} else {
//since connection did have an error, other waiting connection might too
//forcing validation when borrowed next time, even if "minDelayValidation" is not reached.
currConn.lastUse = Math.min(Date.now() - opts.minDelayValidation, currConn.lastUse);
}
idx++;
}
pool.emit('_remove-conn');
});
connectionInCreation = false;
idleConnections.push(conn);
pool.emit('_idle-conn');
process.nextTick(() => pool.emit('connection', conn));
};
this._releaseConnection = function (conn) {
removeLeakProcess(conn);
conn.lastUse = Date.now();
delete activeConnections[conn.threadId];
const pool = this;
if (closed) {
return conn.forceEnd().catch(() => {
return Promise.resolve();
});
} else if (conn.isValid()) {
pool.emit('release', conn);
idleConnections.push(conn);
process.nextTick(() => pool.emit('_idle-conn'));
} else {
ensurePoolSize(pool);
}
};
/**
* Grow pool connections until reaching connection limit.
*/
const ensurePoolSize = function (pool) {
if (
!connectionInCreation &&
pool.idleConnections() < opts.minimumIdle &&
pool.totalConnections() < opts.connectionLimit &&
!closed
) {
connectionInCreation = true;
process.nextTick(() => {
const timeoutEnd = Date.now() + opts.initializationTimeout;
if (!closed) {
connectionCreationLoop(pool, 0, timeoutEnd)
.then((conn) => {
if (closed) {
return conn.forceEnd().catch((err) => {});
}
addPoolConnection(pool, conn);
})
.catch((err) => {
if (pool.totalConnections() === 0) {
const task = taskQueue.shift();
if (task) {
firstTaskTimeout = clearTimeout(firstTaskTimeout);
process.nextTick(task.reject, err);
resetTimeoutToNextTask();
}
} else if (!closed) {
console.error(`pool fail to create connection (${err.message})`);
}
//delay next try
setTimeout(() => {
connectionInCreation = false;
if (taskQueue.size() > 0) {
ensurePoolSize(pool);
}
}, 500);
});
}
});
}
};
const resetTimeoutToNextTask = () => {
//handle next Timer
const currTime = Date.now();
let nextTask;
while ((nextTask = taskQueue.peekFront())) {
if (nextTask.timeout < currTime) {
timeoutTask(nextTask);
} else {
firstTaskTimeout = setTimeout(rejectAndResetTimeout, nextTask.timeout - currTime, nextTask);
return;
}
}
};
/**
* Permit to remove idle connection if unused for some time.
* @param pool current pool
*/
const idleMaintainer = function (pool) {
let toRemove = Math.max(1, pool.idleConnections() - opts.minimumIdle);
while (toRemove > 0) {
const conn = idleConnections.peek();
--toRemove;
if (conn && conn.lastUse + opts.idleTimeout * 1000 < Date.now()) {
idleConnections.shift();
conn.forceEnd().catch((err) => {});
continue;
}
break;
}
ensurePoolSize(pool);
};
this._discardConnection = (conn) => {
removeLeakProcess(conn);
delete activeConnections[conn.threadId];
conn.forceEnd().catch((err) => {});
this.emit('_remove-conn');
};
const logLeak = (conn) => {
console.log(
'Possible connection leak on thread ' +
conn.info.threadId +
' (connection not returned to pool since ' +
(Date.now() - conn.lastUse) +
'ms. Did connection.released() been implemented'
);
conn.leaked = true;
};
const _initLeakProcess = (conn) => {
conn.lastUse = Date.now();
conn.leaked = false;
conn.leakProcess = setTimeout(logLeak, opts.leakDetectionTimeout, conn);
};
const _removeLeakProcess = (conn) => {
conn.leakProcess = clearTimeout(conn.leakProcess);
if (conn.leaked) {
console.log(
'Previous possible leak connection with thread ' +
conn.info.threadId +
' was returned to pool'
);
}
};
/**
* Launch next waiting task request if available connections.
*/
const handleTaskQueue = function () {
firstTaskTimeout = clearTimeout(firstTaskTimeout);
const task = taskQueue.shift();
if (task) {
const conn = idleConnections.shift();
if (conn) {
initLeakProcess(conn);
this.emit('acquire', conn);
activeConnections[conn.threadId] = conn;
resetTimeoutToNextTask();
processTask(conn, task.sql, task.values, task.isBatch)
.then(task.resolve)
.catch(task.reject);
} else {
taskQueue.unshift(task);
}
}
};
const opts = options;
let closed = false;
let connectionInCreation = false;
const initLeakProcess = opts.leakDetectionTimeout > 0 ? _initLeakProcess : () => {};
const removeLeakProcess = opts.leakDetectionTimeout > 0 ? _removeLeakProcess : () => {};
const idleConnections = new Queue();
const activeConnections = {};
const taskQueue = new Queue();
let idleMaintainingTask;
let firstTaskTimeout;
Object.defineProperty(this, 'closed', {
get() {
return closed;
}
});
EventEmitter.call(this);
this.on('_idle-conn', handleTaskQueue.bind(this));
this.on('_remove-conn', ensurePoolSize.bind(this, this));
this.on('connection', ensurePoolSize.bind(this, this));
}
util.inherits(PoolBase, EventEmitter);
module.exports = PoolBase;

201
node_modules/mariadb/lib/pool-callback.js generated vendored Normal file
View File

@@ -0,0 +1,201 @@
'use strict';
const PoolBase = require('./pool-base');
const ConnectionCallback = require('./connection-callback');
const Errors = require('./misc/errors');
const util = require('util');
function PoolCallback(options) {
const processTaskCallback = function (conn, sql, values, isBatch) {
if (sql) {
return new Promise((resolve, reject) => {
const fct = isBatch ? conn.batch : conn.query;
fct(sql, values, (err, rows, fields) => {
conn.releaseWithoutError();
if (err) {
reject(err);
return;
}
return resolve(rows);
});
});
} else {
return Promise.resolve(conn);
}
};
const pingPromise = function (conn) {
return new Promise((resolve, reject) => {
conn.ping(options.pingTimeout, (err) => {
if (err) {
reject(err);
} else resolve();
});
});
};
const createConnectionPoolCallback = function (pool) {
const conn = new ConnectionCallback(options.connOptions);
return new Promise(function (resolve, reject) {
conn.connect((err) => {
if (err) {
reject(err);
} else {
if (pool.closed) {
//discard connection
conn.end((err) => {});
reject(
Errors.createError(
'Cannot create new connection to pool, pool closed',
true,
null,
'08S01',
Errors.ER_ADD_CONNECTION_CLOSED_POOL,
null
)
);
} else {
const initialEnd = conn.end;
conn.forceEnd = () => {
return new Promise(function (res, rej) {
initialEnd((err) => {
if (err) {
rej(err);
} else {
res();
}
});
});
};
conn.release = function (cb) {
if (pool.closed) {
pool._discardConnection(conn);
if (cb) cb();
return;
}
if (options.noControlAfterUse) {
pool._releaseConnection(conn);
if (cb) cb();
return;
}
//if server permit it, reset the connection, or rollback only if not
// COM_RESET_CONNECTION exist since mysql 5.7.3 and mariadb 10.2.4
// but not possible to use it with mysql waiting for https://bugs.mysql.com/bug.php?id=97633 correction.
// and mariadb only since https://jira.mariadb.org/browse/MDEV-18281
let revertFunction = conn.rollback;
if (
options.resetAfterUse &&
conn.info.isMariaDB() &&
((conn.info.serverVersion.minor === 2 && conn.info.hasMinVersion(10, 2, 22)) ||
conn.info.hasMinVersion(10, 3, 13))
) {
revertFunction = conn.reset;
}
revertFunction((errCall) => {
if (errCall) {
//uncertain connection state.
pool._discardConnection(conn);
if (cb) cb();
return;
} else {
pool._releaseConnection(conn);
}
if (cb) cb();
});
};
conn.end = conn.release;
conn.releaseWithoutError = () => {
conn.end((err) => {});
};
resolve(conn);
}
}
});
});
};
PoolBase.call(this, options, processTaskCallback, createConnectionPoolCallback, pingPromise);
const getConnectionPromise = this.getConnection.bind(this);
const endPromise = this.end.bind(this);
const queryPromise = this.query.bind(this);
const batchPromise = this.batch.bind(this);
const emptyError = (err) => {};
//*****************************************************************
// internal equivalent with callback of promised functions
//*****************************************************************
const _getConnectionCallback = (callback) => {
getConnectionPromise()
.then((conn) => {
if (callback) callback(null, conn);
})
.catch(callback || emptyError);
};
const _endCallback = (callback) => {
endPromise()
.then(() => {
if (callback) callback(null);
})
.catch(callback || emptyError);
};
/**
* Execute query using text protocol with callback emit columns/data/end/error
* events to permit streaming big result-set
*
* @param sql sql parameter Object can be used to supersede default option.
* Object must then have sql property.
* @param values object / array of placeholder values (not mandatory)
* @param cb callback
* @returns {Query} query
*/
const _queryCallback = function (sql, values, cb) {
let _cb = cb,
_values = values;
if (typeof values === 'function') {
_cb = values;
_values = undefined;
}
queryPromise(sql, _values)
.then((rows) => {
if (_cb) _cb(null, rows, rows.meta);
})
.catch(_cb || emptyError);
};
const _batchCallback = function (sql, values, cb) {
let _values = values,
_cb = cb;
if (typeof values === 'function') {
_cb = values;
_values = undefined;
}
batchPromise(sql, _values)
.then((rows) => {
if (_cb) _cb(null, rows, rows.meta);
})
.catch(_cb || emptyError);
};
//*****************************************************************
// replacing public promise function with callback equivalent
//*****************************************************************
this.end = _endCallback;
this.query = _queryCallback;
this.batch = _batchCallback;
this.getConnection = _getConnectionCallback;
}
util.inherits(PoolCallback, PoolBase);
module.exports = PoolCallback;

66
node_modules/mariadb/lib/pool-cluster-callback.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
'use strict';
const PoolCluster = require('./pool-cluster');
const util = require('util');
/**
* Create a new Cluster.
* Cluster handle pools with patterns and handle failover / distributed load
* according to selectors (round robin / random / ordered )
*
* @param args cluster argurments. see pool-cluster-options.
* @constructor
*/
function PoolClusterCallback(args) {
PoolCluster.call(this, args);
this.setCallback();
const initialGetConnection = this.getConnection.bind(this);
const initialEnd = this.end.bind(this);
/**
* End cluster (and underlying pools).
*
* @param callback - not mandatory
*/
this.end = (callback) => {
if (callback && typeof callback !== 'function') {
throw new Error('callback parameter must be a function');
}
const endingFct = callback ? callback : () => {};
initialEnd()
.then(() => {
endingFct();
})
.catch(endingFct);
};
/**
* Get connection from available pools matching pattern, according to selector
*
* @param pattern pattern filter (not mandatory)
* @param selector node selector ('RR','RANDOM' or 'ORDER')
* @param callback callback function
*/
this.getConnection = (pattern, selector, callback) => {
let pat = pattern,
sel = selector,
cal = callback;
if (typeof pattern === 'function') {
pat = null;
sel = null;
cal = pattern;
} else if (typeof selector === 'function') {
sel = null;
cal = selector;
}
const endingFct = cal ? cal : (conn) => {};
initialGetConnection(pat, sel, endingFct);
};
}
util.inherits(PoolClusterCallback, PoolCluster);
module.exports = PoolClusterCallback;

407
node_modules/mariadb/lib/pool-cluster.js generated vendored Normal file
View File

@@ -0,0 +1,407 @@
'use strict';
const PoolClusterOptions = require('./config/pool-cluster-options');
const PoolOptions = require('./config/pool-options');
const Pool = require('./pool-promise');
const PoolCallback = require('./pool-callback');
const FilteredPoolCluster = require('./filtered-pool-cluster');
const EventEmitter = require('events');
const util = require('util');
/**
* Create a new Cluster.
* Cluster handle pools with patterns and handle failover / distributed load
* according to selectors (round robin / random / ordered )
*
* @param args cluster argurments. see pool-cluster-options.
* @constructor
*/
function PoolCluster(args) {
const opts = new PoolClusterOptions(args);
const nodes = {};
let cachedPatterns = {};
let nodeCounter = 0;
EventEmitter.call(this);
/**
* Add a new pool node to cluster.
*
* @param id identifier
* @param config pool configuration
*/
this.add = (id, config) => {
let identifier;
if (typeof id === 'string' || id instanceof String) {
identifier = id;
if (nodes[identifier])
throw new Error("Node identifier '" + identifier + "' already exist !");
} else {
identifier = 'PoolNode-' + nodeCounter++;
config = id;
}
const options = new PoolOptions(config);
const pool = _createPool(options);
pool.initialize();
nodes[identifier] = pool;
};
/**
* End cluster (and underlying pools).
*
* @return {Promise<any[]>}
*/
this.end = () => {
cachedPatterns = {};
const poolEndPromise = [];
Object.keys(nodes).forEach((pool) => {
poolEndPromise.push(nodes[pool].end());
delete nodes[pool];
});
return Promise.all(poolEndPromise);
};
this.of = (pattern, selector) => {
return new FilteredPoolCluster(this, pattern, selector);
};
/**
* Remove nodes according to pattern.
*
* @param pattern pattern
*/
this.remove = (pattern) => {
if (!pattern) throw new Error('pattern parameter in Cluster.remove(pattern) is mandatory');
const regex = RegExp(pattern);
Object.keys(nodes).forEach((key) => {
if (regex.test(key)) {
nodes[key].end();
delete nodes[key];
cachedPatterns = {};
}
});
};
/**
* Get connection from available pools matching pattern, according to selector
*
* @param pattern pattern filter (not mandatory)
* @param selector node selector ('RR','RANDOM' or 'ORDER')
* @return {Promise}
*/
this.getConnection = (pattern, selector) => {
return _getConnection(this, pattern, selector);
};
/**
* Force using callback methods.
*/
this.setCallback = () => {
this.getConnection = _getConnectionCallback.bind(this, this);
_createPool = _createPoolCallback;
};
/**
* Get connection from available pools matching pattern, according to selector
* with additional parameter to avoid reusing failing node
*
* @param pattern pattern filter (not mandatory)
* @param selector node selector ('RR','RANDOM' or 'ORDER')
* @param avoidNodeKey failing node
* @param lastError last error
* @return {Promise}
* @private
*/
const _getConnection = (cluster, pattern, selector, avoidNodeKey, lastError) => {
const matchingNodeList = _matchingNodes(pattern || /^/);
if (matchingNodeList.length === 0) {
if (Object.keys(nodes).length === 0 && !lastError) {
return Promise.reject(
new Error(
'No node have been added to cluster ' +
'or nodes have been removed due to too much connection error'
)
);
}
if (avoidNodeKey === undefined)
return Promise.reject(new Error("No node found for pattern '" + pattern + "'"));
const errMsg =
"No Connection available for '" +
pattern +
"'" +
(lastError ? '. Last connection error was: ' + lastError.message : '');
return Promise.reject(new Error(errMsg));
}
const retry = _getConnection.bind(this, this, pattern, selector);
try {
const nodeKey = _selectPool(matchingNodeList, selector, avoidNodeKey);
return _handleConnectionError(cluster, matchingNodeList, nodeKey, retry);
} catch (e) {
return Promise.reject(e);
}
};
let _createPool = (options) => {
return new Pool(options, false);
};
const _createPoolCallback = (options) => {
return new PoolCallback(options, false);
};
/**
* Get connection from available pools matching pattern, according to selector
* with additional parameter to avoid reusing failing node
*
* @param pattern pattern filter (not mandatory)
* @param selector node selector ('RR','RANDOM' or 'ORDER')
* @param callback callback function
* @param avoidNodeKey failing node
* @param lastError last error
* @private
*/
const _getConnectionCallback = (
cluster,
pattern,
selector,
callback,
avoidNodeKey,
lastError
) => {
const matchingNodeList = _matchingNodes(pattern || /^/);
if (matchingNodeList.length === 0) {
if (Object.keys(nodes).length === 0 && !lastError) {
callback(
new Error(
'No node have been added to cluster ' +
'or nodes have been removed due to too much connection error'
)
);
return;
}
if (avoidNodeKey === undefined)
callback(new Error("No node found for pattern '" + pattern + "'"));
const errMsg =
"No Connection available for '" +
pattern +
"'" +
(lastError ? '. Last connection error was: ' + lastError.message : '');
callback(new Error(errMsg));
return;
}
const retry = _getConnectionCallback.bind(this, this, pattern, selector, callback);
try {
const nodeKey = _selectPool(matchingNodeList, selector, avoidNodeKey);
_handleConnectionCallbackError(this, matchingNodeList, nodeKey, retry, callback);
} catch (e) {
callback(e);
}
};
/**
* Selecting nodes according to pattern.
*
* @param pattern pattern
* @return {*}
* @private
*/
const _matchingNodes = (pattern) => {
if (cachedPatterns[pattern]) return cachedPatterns[pattern];
const regex = RegExp(pattern);
const matchingNodeList = [];
Object.keys(nodes).forEach((key) => {
if (regex.test(key)) {
matchingNodeList.push(key);
}
});
cachedPatterns[pattern] = matchingNodeList;
return matchingNodeList;
};
/**
* Select next node to be chosen in nodeList according to selector and failed nodes.
*
* @param nodeList current node list
* @param selectorParam selector
* @param avoidNodeKey last failing node to avoid selecting this one.
* @return {Promise}
* @private
*/
const _selectPool = (nodeList, selectorParam, avoidNodeKey) => {
const selector = selectorParam || opts.defaultSelector;
let retry = 0;
let selectorFct;
let nodeKey;
switch (selector) {
case 'RR':
selectorFct = roundRobinSelector;
break;
case 'RANDOM':
selectorFct = randomSelector;
break;
case 'ORDER':
selectorFct = orderedSelector;
break;
default:
throw new Error(
"Wrong selector value '" + selector + "'. Possible values are 'RR','RANDOM' or 'ORDER'"
);
}
nodeKey = selectorFct(nodeList, retry);
while (
(avoidNodeKey === nodeKey || nodes[nodeKey].blacklistedUntil > Date.now()) &&
retry < nodeList.length - 1
) {
retry++;
nodeKey = selectorFct(nodeList, retry);
}
return nodeKey;
};
/**
* Round robin selector: using nodes one after the other.
*
* @param nodeList node list
* @return {String}
*/
const roundRobinSelector = (nodeList) => {
let lastRoundRobin = nodeList.lastRrIdx;
if (lastRoundRobin === undefined) lastRoundRobin = -1;
if (++lastRoundRobin >= nodeList.length) lastRoundRobin = 0;
nodeList.lastRrIdx = lastRoundRobin;
return nodeList[lastRoundRobin];
};
/**
* Random selector: use a random node.
*
* @param nodeList node list
* @return {String}
*/
const randomSelector = (nodeList) => {
let randomIdx = Math.floor(Math.random() * nodeList.length);
return nodeList[randomIdx];
};
/**
* Ordered selector: always use the nodes in sequence, unless failing.
*
* @param nodeList node list
* @param retry sequence number if last node is tagged has failing
* @return {String}
*/
const orderedSelector = (nodeList, retry) => {
return nodeList[retry];
};
/**
* Connect, or if fail handle retry / set timeout error
*
* @param cluster current cluster
* @param nodeList current node list
* @param nodeKey node name to connect
* @param retryFct retry function
* @return {Promise}
* @private
*/
const _handleConnectionError = (cluster, nodeList, nodeKey, retryFct) => {
const node = nodes[nodeKey];
return node
.getConnection()
.then((conn) => {
node.errorCount = 0;
return Promise.resolve(conn);
})
.catch((err) => {
node.errorCount = node.errorCount ? node.errorCount + 1 : 1;
node.blacklistedUntil = Date.now() + opts.restoreNodeTimeout;
if (
opts.removeNodeErrorCount &&
node.errorCount >= opts.removeNodeErrorCount &&
nodes[nodeKey]
) {
delete nodes[nodeKey];
cachedPatterns = {};
delete nodeList.lastRrIdx;
process.nextTick(() => cluster.emit('remove', nodeKey));
//remove node from configuration if not already removed
node.end().catch((err) => {
// dismiss error
});
}
if (nodeList.length !== 0 && opts.canRetry) {
return retryFct(nodeKey, err);
}
return Promise.reject(err);
});
};
/**
* Connect, or if fail handle retry / set timeout error
*
* @param cluster current cluster
* @param nodeList current node list
* @param nodeKey node name to connect
* @param retryFct retry function
* @param callback callback function
* @private
*/
const _handleConnectionCallbackError = (cluster, nodeList, nodeKey, retryFct, callback) => {
const node = nodes[nodeKey];
node.getConnection((err, conn) => {
if (err) {
node.errorCount = node.errorCount ? node.errorCount + 1 : 1;
node.blacklistedUntil = Date.now() + opts.restoreNodeTimeout;
if (
opts.removeNodeErrorCount &&
node.errorCount >= opts.removeNodeErrorCount &&
nodes[nodeKey]
) {
delete nodes[nodeKey];
cachedPatterns = {};
delete nodeList.lastRrIdx;
process.nextTick(() => cluster.emit('remove', nodeKey));
//remove node from configuration if not already removed
node.end(() => {
//dismiss error
});
if (nodeList.length === 0) return Promise.reject(err);
}
if (opts.canRetry) return retryFct(nodeKey, err);
callback(err);
} else {
node.errorCount = 0;
callback(null, conn);
}
});
};
//*****************************************************************
// internal public testing methods
//*****************************************************************
function TestMethods() {}
TestMethods.prototype.getNodes = () => {
return nodes;
};
this.__tests = new TestMethods();
}
util.inherits(PoolCluster, EventEmitter);
module.exports = PoolCluster;

107
node_modules/mariadb/lib/pool-promise.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
'use strict';
const Connection = require('./connection');
const PoolBase = require('./pool-base');
const Errors = require('./misc/errors');
const util = require('util');
function PoolPromise(options) {
const processTaskPromise = function (conn, sql, values, isBatch) {
if (sql) {
const fct = isBatch ? conn.batch : conn.query;
return fct(sql, values)
.then((res) => {
conn.releaseWithoutError();
return Promise.resolve(res);
})
.catch((err) => {
conn.releaseWithoutError();
return Promise.reject(err);
});
}
return Promise.resolve(conn);
};
/**
* Add connection to pool.
*/
const createConnectionPoolPromise = function (pool) {
const conn = new Connection(options.connOptions);
return conn
.connect()
.then(() => {
if (pool.closed) {
conn
.end()
.then(() => {})
.catch(() => {});
return Promise.reject(
Errors.createError(
'Cannot create new connection to pool, pool closed',
true,
null,
'08S01',
Errors.ER_ADD_CONNECTION_CLOSED_POOL,
null
)
);
}
conn.releaseWithoutError = () => {
conn.release().catch(() => {});
};
conn.forceEnd = conn.end;
conn.release = () => {
if (pool.closed) {
pool._discardConnection(conn);
return Promise.resolve();
}
if (options.noControlAfterUse) {
pool._releaseConnection(conn);
return Promise.resolve();
}
//if server permit it, reset the connection, or rollback only if not
// COM_RESET_CONNECTION exist since mysql 5.7.3 and mariadb 10.2.4
// but not possible to use it with mysql waiting for https://bugs.mysql.com/bug.php?id=97633 correction.
// and mariadb only since https://jira.mariadb.org/browse/MDEV-18281
let revertFunction = conn.rollback;
if (
options.resetAfterUse &&
conn.info.isMariaDB() &&
((conn.info.serverVersion.minor === 2 && conn.info.hasMinVersion(10, 2, 22)) ||
conn.info.hasMinVersion(10, 3, 13))
) {
revertFunction = conn.reset;
}
return revertFunction()
.then(() => {
pool._releaseConnection(conn);
return Promise.resolve();
})
.catch((err) => {
//uncertain connection state.
// discard it
pool._discardConnection(conn);
return Promise.resolve();
});
};
conn.end = conn.release;
return Promise.resolve(conn);
})
.catch((err) => {
return Promise.reject(err);
});
};
PoolBase.call(this, options, processTaskPromise, createConnectionPoolPromise, (conn) =>
conn.ping(options.pingTimeout)
);
}
util.inherits(PoolPromise, PoolBase);
module.exports = PoolPromise;