Comparing version 3.3.0 to 3.3.1
@@ -16,3 +16,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const Connection = require('./lib/connection'); | ||
const CommandParameter = require('./lib/command-parameter'); | ||
@@ -73,3 +72,3 @@ module.exports.version = require('./package.json').version; | ||
.finally(() => { | ||
new Promise(conn.end.bind(conn, new CommandParameter())).catch(console.log); | ||
new Promise(conn.end.bind(conn, {})).catch(console.log); | ||
}); | ||
@@ -76,0 +75,0 @@ } catch (err) { |
@@ -407,3 +407,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const randomSelector = (nodeList) => { | ||
let randomIdx = Math.floor(Math.random() * nodeList.length); | ||
let randomIdx = ~~(Math.random() * nodeList.length); | ||
return nodeList[randomIdx]; | ||
@@ -410,0 +410,0 @@ }; |
@@ -19,3 +19,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
super(resolve, reject, connOpts, cmdParam); | ||
this.writeParam = BinaryEncoder.writeParam; | ||
this.cmdOpts = cmdParam.opts; | ||
@@ -92,3 +91,3 @@ this.binary = true; | ||
// like 'SELECT ?' returning same type of value | ||
if (Number.isSafeInteger(val) && val >= -2147483648 && val < 2147483647) { | ||
if (Number.isInteger(val) && val >= -2147483648 && val < 2147483647) { | ||
parameterHeaderType[i] = FieldType.INT; | ||
@@ -103,4 +102,4 @@ break; | ||
case 'object': | ||
if (val instanceof Date) { | ||
parameterHeaderType[i] = FieldType.TIMESTAMP; | ||
if (Object.prototype.toString.call(val) === '[object Date]') { | ||
parameterHeaderType[i] = FieldType.DATETIME; | ||
} else if (Buffer.isBuffer(val)) { | ||
@@ -167,3 +166,3 @@ parameterHeaderType[i] = FieldType.BLOB; | ||
// like 'SELECT ?' returning same type of value | ||
if (Number.isSafeInteger(val) && val >= -2147483648 && val < 2147483647) { | ||
if (Number.isInteger(val) && val >= -2147483648 && val < 2147483647) { | ||
if (parameterHeaderType[i] !== FieldType.INT) return false; | ||
@@ -178,3 +177,3 @@ break; | ||
case 'object': | ||
if (val instanceof Date) { | ||
if (Object.prototype.toString.call(val) === '[object Date]') { | ||
if (parameterHeaderType[i] !== FieldType.TIMESTAMP) return false; | ||
@@ -252,2 +251,3 @@ } else if (Buffer.isBuffer(val)) { | ||
if (err) { | ||
this.sending = false; | ||
this.throwError(err, info); | ||
@@ -291,7 +291,7 @@ return; | ||
]); | ||
this.writeParam(out, param, this.opts, info); | ||
BinaryEncoder.writeParam(out, param, this.opts, info); | ||
} | ||
} else { | ||
out.writeInt8(0x00); // value follow | ||
this.writeParam(out, param, this.opts, info); | ||
BinaryEncoder.writeParam(out, param, this.opts, info); | ||
} | ||
@@ -298,0 +298,0 @@ } else { |
@@ -5,3 +5,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
'use strict'; | ||
const CommandParameter = require('../../command-parameter'); | ||
const Errors = require('../../misc/errors'); | ||
@@ -68,3 +67,8 @@ const ExecuteStream = require('../execute-stream'); | ||
const cmdParam = new CommandParameter(this.query, values, _opts, _cb); | ||
const cmdParam = { | ||
sql: this.query, | ||
values: values, | ||
opts: _opts, | ||
callback: _cb | ||
}; | ||
if (stack) cmdParam.stack = stack; | ||
@@ -110,3 +114,8 @@ const conn = this.conn; | ||
const cmdParam = new CommandParameter(this.query, values, _opts, _cb); | ||
const cmdParam = { | ||
sql: this.query, | ||
values: values, | ||
opts: _opts, | ||
callback: _cb | ||
}; | ||
if (stack) cmdParam.stack = stack; | ||
@@ -116,3 +125,3 @@ | ||
if (this.conn.opts.logger.error) cmd.on('error', this.conn.opts.logger.error); | ||
this.conn.addCommand(cmd); | ||
this.conn.addCommand(cmd, true); | ||
return cmd.inStream; | ||
@@ -119,0 +128,0 @@ } |
@@ -112,9 +112,11 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
class BaseStringParser { | ||
constructor(readFct, saveBuf) { | ||
constructor(encoding, readFct, saveBuf, initialPos) { | ||
this.buf = saveBuf; | ||
this.encoding = encoding; | ||
this.readString = readFct; | ||
this.initialPos = initialPos; | ||
} | ||
_readIdentifier(skip) { | ||
let pos = 0; | ||
let pos = this.initialPos; | ||
while (skip-- > 0) { | ||
@@ -129,3 +131,3 @@ const type = this.buf[pos++]; | ||
return this.readString(this.buf, pos, len); | ||
return this.readString(this.encoding, this.buf, pos, len); | ||
} | ||
@@ -160,3 +162,3 @@ | ||
constructor(packet) { | ||
packet.skip(4); // skip 'def' | ||
packet.skip(packet.readMetadataLength()); //catalog | ||
const initPos = packet.pos; | ||
@@ -169,7 +171,3 @@ packet.skip(packet.readMetadataLength()); //schema | ||
const len = packet.pos - initPos; | ||
const saveBuf = Buffer.allocUnsafe(packet.pos - initPos); | ||
for (let i = 0; i < len; i++) saveBuf[i] = packet.buf[initPos + i]; | ||
super(packet.readString.bind(packet), saveBuf); | ||
super(packet.encoding, packet.constructor.readString, packet.buf, initPos); | ||
} | ||
@@ -185,3 +183,3 @@ } | ||
constructor(packet) { | ||
packet.skip(4); // skip 'def' | ||
packet.skip(packet.readMetadataLength()); //catalog | ||
const initPos = packet.pos; | ||
@@ -194,7 +192,3 @@ packet.skip(packet.readMetadataLength()); //schema | ||
const len = packet.pos - initPos; | ||
const saveBuf = Buffer.allocUnsafe(packet.pos - initPos); | ||
for (let i = 0; i < len; i++) saveBuf[i] = packet.buf[initPos + i]; | ||
super(packet.readString.bind(packet), saveBuf); | ||
super(packet.encoding, packet.constructor.readString, packet.buf, initPos); | ||
this.colName = colName; | ||
@@ -201,0 +195,0 @@ } |
@@ -9,116 +9,111 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
class BinaryDecoder { | ||
static newRow(packet, columns) { | ||
packet.skip(1); // skip 0x00 header. | ||
const len = Math.floor((columns.length + 9) / 8); | ||
const nullBitMap = new Array(len); | ||
for (let i = 0; i < len; i++) nullBitMap[i] = packet.readUInt8(); | ||
return nullBitMap; | ||
} | ||
module.exports.newRow = function (packet, columns) { | ||
packet.skip(1); // skip 0x00 header. | ||
const len = ~~((columns.length + 9) / 8); | ||
const nullBitMap = new Array(len); | ||
for (let i = 0; i < len; i++) nullBitMap[i] = packet.readUInt8(); | ||
return nullBitMap; | ||
}; | ||
module.exports.castWrapper = function (column, packet, opts, nullBitmap, index) { | ||
column.string = () => (isNullBitmap(index, nullBitmap) ? null : packet.readStringLengthEncoded()); | ||
column.buffer = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBufferLengthEncoded()); | ||
column.float = () => (isNullBitmap(index, nullBitmap) ? null : packet.readFloat()); | ||
column.tiny = () => | ||
isNullBitmap(index, nullBitmap) ? null : column.signed() ? packet.readInt8() : packet.readUInt8(); | ||
column.short = () => | ||
isNullBitmap(index, nullBitmap) ? null : column.signed() ? packet.readInt16() : packet.readUInt16(); | ||
column.int = () => (isNullBitmap(index, nullBitmap) ? null : packet.readInt32()); | ||
column.long = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBigInt64()); | ||
column.decimal = () => (isNullBitmap(index, nullBitmap) ? null : packet.readDecimalLengthEncoded()); | ||
column.date = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDate(opts)); | ||
column.datetime = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDateTime()); | ||
static castWrapper(column, packet, opts, nullBitmap, index) { | ||
column.string = () => (isNullBitmap(index, nullBitmap) ? null : packet.readStringLengthEncoded()); | ||
column.buffer = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBufferLengthEncoded()); | ||
column.float = () => (isNullBitmap(index, nullBitmap) ? null : packet.readFloat()); | ||
column.tiny = () => | ||
isNullBitmap(index, nullBitmap) ? null : column.signed() ? packet.readInt8() : packet.readUInt8(); | ||
column.short = () => | ||
isNullBitmap(index, nullBitmap) ? null : column.signed() ? packet.readInt16() : packet.readUInt16(); | ||
column.int = () => (isNullBitmap(index, nullBitmap) ? null : packet.readInt32()); | ||
column.long = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBigInt64()); | ||
column.decimal = () => (isNullBitmap(index, nullBitmap) ? null : packet.readDecimalLengthEncoded()); | ||
column.date = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDate(opts)); | ||
column.datetime = () => (isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDateTime()); | ||
column.geometry = () => { | ||
let defaultVal = null; | ||
if (column.dataTypeName) { | ||
switch (column.dataTypeName) { | ||
case 'point': | ||
defaultVal = { type: 'Point' }; | ||
break; | ||
case 'linestring': | ||
defaultVal = { type: 'LineString' }; | ||
break; | ||
case 'polygon': | ||
defaultVal = { type: 'Polygon' }; | ||
break; | ||
case 'multipoint': | ||
defaultVal = { type: 'MultiPoint' }; | ||
break; | ||
case 'multilinestring': | ||
defaultVal = { type: 'MultiLineString' }; | ||
break; | ||
case 'multipolygon': | ||
defaultVal = { type: 'MultiPolygon' }; | ||
break; | ||
default: | ||
defaultVal = { type: column.dataTypeName }; | ||
break; | ||
} | ||
column.geometry = () => { | ||
let defaultVal = null; | ||
if (column.dataTypeName) { | ||
switch (column.dataTypeName) { | ||
case 'point': | ||
defaultVal = { type: 'Point' }; | ||
break; | ||
case 'linestring': | ||
defaultVal = { type: 'LineString' }; | ||
break; | ||
case 'polygon': | ||
defaultVal = { type: 'Polygon' }; | ||
break; | ||
case 'multipoint': | ||
defaultVal = { type: 'MultiPoint' }; | ||
break; | ||
case 'multilinestring': | ||
defaultVal = { type: 'MultiLineString' }; | ||
break; | ||
case 'multipolygon': | ||
defaultVal = { type: 'MultiPolygon' }; | ||
break; | ||
default: | ||
defaultVal = { type: column.dataTypeName }; | ||
break; | ||
} | ||
} | ||
if (isNullBitmap(index, nullBitmap)) { | ||
return defaultVal; | ||
if (isNullBitmap(index, nullBitmap)) { | ||
return defaultVal; | ||
} | ||
return packet.readGeometry(defaultVal); | ||
}; | ||
}; | ||
module.exports.parser = function (col, opts) { | ||
// set reader function read(col, packet, index, nullBitmap, opts, throwUnexpectedError) | ||
// this permit for multi-row result-set to avoid resolving type parsing each data. | ||
// return constant parser (function not depending on column info other than type) | ||
const defaultParser = col.signed() | ||
? DEFAULT_SIGNED_PARSER_TYPE[col.columnType] | ||
: DEFAULT_UNSIGNED_PARSER_TYPE[col.columnType]; | ||
if (defaultParser) return defaultParser; | ||
// parser depending on column info | ||
switch (col.columnType) { | ||
case FieldType.BIGINT: | ||
if (col.signed()) { | ||
return opts.bigIntAsNumber || opts.supportBigNumbers ? readBigintAsIntBinarySigned : readBigintBinarySigned; | ||
} | ||
return packet.readGeometry(defaultVal); | ||
}; | ||
} | ||
static parser(col, opts) { | ||
// set reader function read(col, packet, index, nullBitmap, opts, throwUnexpectedError) | ||
// this permit for multi-row result-set to avoid resolving type parsing each data. | ||
return opts.bigIntAsNumber || opts.supportBigNumbers ? readBigintAsIntBinaryUnsigned : readBigintBinaryUnsigned; | ||
// return constant parser (function not depending on column info other than type) | ||
const defaultParser = col.signed() | ||
? DEFAULT_SIGNED_PARSER_TYPE[col.columnType] | ||
: DEFAULT_UNSIGNED_PARSER_TYPE[col.columnType]; | ||
if (defaultParser) return defaultParser; | ||
case FieldType.DATETIME: | ||
case FieldType.TIMESTAMP: | ||
return opts.dateStrings ? readTimestampStringBinary.bind(null, col.scale) : readTimestampBinary; | ||
// parser depending on column info | ||
switch (col.columnType) { | ||
case FieldType.BIGINT: | ||
if (col.signed()) { | ||
return opts.bigIntAsNumber || opts.supportBigNumbers ? readBigintAsIntBinarySigned : readBigintBinarySigned; | ||
} | ||
return opts.bigIntAsNumber || opts.supportBigNumbers ? readBigintAsIntBinaryUnsigned : readBigintBinaryUnsigned; | ||
case FieldType.DECIMAL: | ||
case FieldType.NEWDECIMAL: | ||
return col.scale === 0 ? readDecimalAsIntBinary : readDecimalBinary; | ||
case FieldType.DATETIME: | ||
case FieldType.TIMESTAMP: | ||
return opts.dateStrings ? readTimestampStringBinary.bind(null, col.scale) : readTimestampBinary; | ||
case FieldType.GEOMETRY: | ||
let defaultVal = col.__getDefaultGeomVal(); | ||
return readGeometryBinary.bind(null, defaultVal); | ||
case FieldType.DECIMAL: | ||
case FieldType.NEWDECIMAL: | ||
return col.scale === 0 ? readDecimalAsIntBinary : readDecimalBinary; | ||
case FieldType.BIT: | ||
if (col.columnLength === 1 && opts.bitOneIsBoolean) { | ||
return readBitBinaryBoolean; | ||
} | ||
return readBinaryBuffer; | ||
case FieldType.GEOMETRY: | ||
let defaultVal = col.__getDefaultGeomVal(); | ||
return readGeometryBinary.bind(null, defaultVal); | ||
case FieldType.BIT: | ||
if (col.columnLength === 1 && opts.bitOneIsBoolean) { | ||
return readBitBinaryBoolean; | ||
} | ||
default: | ||
if (col.dataTypeFormat && col.dataTypeFormat === 'json' && opts.autoJsonMap) { | ||
return readJsonBinary; | ||
} | ||
if (col.collation.index === 63) { | ||
return readBinaryBuffer; | ||
default: | ||
if (col.dataTypeFormat && col.dataTypeFormat === 'json' && opts.autoJsonMap) { | ||
return readJsonBinary; | ||
} | ||
if (col.collation.index === 63) { | ||
return readBinaryBuffer; | ||
} | ||
if (col.isSet()) { | ||
return readBinarySet; | ||
} | ||
return readStringBinary; | ||
} | ||
} | ||
if (col.isSet()) { | ||
return readBinarySet; | ||
} | ||
return readStringBinary; | ||
} | ||
} | ||
}; | ||
const isNullBitmap = (index, nullBitmap) => { | ||
return (nullBitmap[Math.floor((index + 2) / 8)] & (1 << (index + 2) % 8)) > 0; | ||
return (nullBitmap[~~((index + 2) / 8)] & (1 << (index + 2) % 8)) > 0; | ||
}; | ||
module.exports = BinaryDecoder; | ||
const readTinyBinarySigned = (packet, opts, throwUnexpectedError, nullBitmap, index) => | ||
@@ -125,0 +120,0 @@ isNullBitmap(index, nullBitmap) ? null : packet.readInt8(); |
@@ -9,92 +9,87 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
class TextDecoder { | ||
static castWrapper(column, packet, opts, nullBitmap, index) { | ||
column.string = () => packet.readStringLengthEncoded(); | ||
column.buffer = () => packet.readBufferLengthEncoded(); | ||
column.float = () => packet.readFloatLengthCoded(); | ||
column.tiny = () => packet.readIntLengthEncoded(); | ||
column.short = () => packet.readIntLengthEncoded(); | ||
column.int = () => packet.readIntLengthEncoded(); | ||
column.long = () => packet.readBigIntLengthEncoded(); | ||
column.decimal = () => packet.readDecimalLengthEncoded(); | ||
column.date = () => packet.readDate(opts); | ||
column.datetime = () => packet.readDateTime(); | ||
module.exports.parser = function (col, opts) { | ||
// set reader function read(col, packet, index, nullBitmap, opts, throwUnexpectedError) | ||
// this permit for multi-row result-set to avoid resolving type parsing each data. | ||
column.geometry = () => { | ||
let defaultVal = null; | ||
if (column.dataTypeName) { | ||
switch (column.dataTypeName) { | ||
case 'point': | ||
defaultVal = { type: 'Point' }; | ||
break; | ||
case 'linestring': | ||
defaultVal = { type: 'LineString' }; | ||
break; | ||
case 'polygon': | ||
defaultVal = { type: 'Polygon' }; | ||
break; | ||
case 'multipoint': | ||
defaultVal = { type: 'MultiPoint' }; | ||
break; | ||
case 'multilinestring': | ||
defaultVal = { type: 'MultiLineString' }; | ||
break; | ||
case 'multipolygon': | ||
defaultVal = { type: 'MultiPolygon' }; | ||
break; | ||
default: | ||
defaultVal = { type: column.dataTypeName }; | ||
break; | ||
} | ||
} | ||
// return constant parser (function not depending on column info other than type) | ||
const defaultParser = DEFAULT_PARSER_TYPE[col.columnType]; | ||
if (defaultParser) return defaultParser; | ||
return packet.readGeometry(defaultVal); | ||
}; | ||
} | ||
// parser depending on column info | ||
switch (col.columnType) { | ||
case FieldType.DECIMAL: | ||
case FieldType.NEWDECIMAL: | ||
return col.scale === 0 ? readDecimalAsIntLengthCoded : readDecimalLengthCoded; | ||
static parser(col, opts) { | ||
// set reader function read(col, packet, index, nullBitmap, opts, throwUnexpectedError) | ||
// this permit for multi-row result-set to avoid resolving type parsing each data. | ||
case FieldType.BIGINT: | ||
if (opts.bigIntAsNumber || opts.supportBigNumbers) return readBigIntAsNumberLengthCoded; | ||
return readBigIntLengthCoded; | ||
// return constant parser (function not depending on column info other than type) | ||
const defaultParser = DEFAULT_PARSER_TYPE[col.columnType]; | ||
if (defaultParser) return defaultParser; | ||
case FieldType.GEOMETRY: | ||
let defaultVal = col.__getDefaultGeomVal(); | ||
return readGeometry.bind(null, defaultVal); | ||
// parser depending on column info | ||
switch (col.columnType) { | ||
case FieldType.DECIMAL: | ||
case FieldType.NEWDECIMAL: | ||
return col.scale === 0 ? readDecimalAsIntLengthCoded : readDecimalLengthCoded; | ||
case FieldType.BIT: | ||
if (col.columnLength === 1 && opts.bitOneIsBoolean) { | ||
return readBitAsBoolean; | ||
} | ||
return readBufferLengthEncoded; | ||
case FieldType.BIGINT: | ||
if (opts.bigIntAsNumber || opts.supportBigNumbers) return readBigIntAsNumberLengthCoded; | ||
return readBigIntLengthCoded; | ||
default: | ||
if (col.dataTypeFormat && col.dataTypeFormat === 'json' && opts.autoJsonMap) { | ||
return readJson; | ||
} | ||
if (col.collation.index === 63) { | ||
return readBufferLengthEncoded; | ||
} | ||
if (col.isSet()) { | ||
return readSet; | ||
} | ||
return readStringLengthEncoded; | ||
} | ||
}; | ||
case FieldType.GEOMETRY: | ||
let defaultVal = col.__getDefaultGeomVal(); | ||
return readGeometry.bind(null, defaultVal); | ||
module.exports.castWrapper = function (column, packet, opts, nullBitmap, index) { | ||
column.string = () => packet.readStringLengthEncoded(); | ||
column.buffer = () => packet.readBufferLengthEncoded(); | ||
column.float = () => packet.readFloatLengthCoded(); | ||
column.tiny = () => packet.readIntLengthEncoded(); | ||
column.short = () => packet.readIntLengthEncoded(); | ||
column.int = () => packet.readIntLengthEncoded(); | ||
column.long = () => packet.readBigIntLengthEncoded(); | ||
column.decimal = () => packet.readDecimalLengthEncoded(); | ||
column.date = () => packet.readDate(opts); | ||
column.datetime = () => packet.readDateTime(); | ||
case FieldType.BIT: | ||
if (col.columnLength === 1 && opts.bitOneIsBoolean) { | ||
return readBitAsBoolean; | ||
} | ||
return readBufferLengthEncoded; | ||
default: | ||
if (col.dataTypeFormat && col.dataTypeFormat === 'json' && opts.autoJsonMap) { | ||
return readJson; | ||
} | ||
if (col.collation.index === 63) { | ||
return readBufferLengthEncoded; | ||
} | ||
if (col.isSet()) { | ||
return readSet; | ||
} | ||
return readStringLengthEncoded; | ||
column.geometry = () => { | ||
let defaultVal = null; | ||
if (column.dataTypeName) { | ||
switch (column.dataTypeName) { | ||
case 'point': | ||
defaultVal = { type: 'Point' }; | ||
break; | ||
case 'linestring': | ||
defaultVal = { type: 'LineString' }; | ||
break; | ||
case 'polygon': | ||
defaultVal = { type: 'Polygon' }; | ||
break; | ||
case 'multipoint': | ||
defaultVal = { type: 'MultiPoint' }; | ||
break; | ||
case 'multilinestring': | ||
defaultVal = { type: 'MultiLineString' }; | ||
break; | ||
case 'multipolygon': | ||
defaultVal = { type: 'MultiPolygon' }; | ||
break; | ||
default: | ||
defaultVal = { type: column.dataTypeName }; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
module.exports = TextDecoder; | ||
return packet.readGeometry(defaultVal); | ||
}; | ||
}; | ||
const readGeometry = (defaultVal, packet, opts, throwUnexpectedError) => packet.readGeometry(defaultVal); | ||
@@ -113,3 +108,3 @@ | ||
if (opts.supportBigNumbers && opts.bigNumberStrings) { | ||
return '' + val; | ||
return `${val}`; | ||
} | ||
@@ -116,0 +111,0 @@ return val; |
@@ -32,3 +32,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
// like 'SELECT ?' returning same type of value | ||
if (Number.isSafeInteger(value) && value >= -2147483648 && value < 2147483647) { | ||
if (Number.isInteger(value) && value >= -2147483648 && value < 2147483647) { | ||
out.writeInt32(value); | ||
@@ -43,3 +43,3 @@ break; | ||
case 'object': | ||
if (value instanceof Date) { | ||
if (Object.prototype.toString.call(value) === '[object Date]') { | ||
out.writeBinaryDate(value); | ||
@@ -46,0 +46,0 @@ } else if (Buffer.isBuffer(value)) { |
@@ -9,3 +9,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const formatDigit = function (val, significantDigit) { | ||
let res = '' + val; | ||
let res = `${val}`; | ||
while (res.length < significantDigit) res = '0' + res; | ||
@@ -20,3 +20,3 @@ return res; | ||
* @param out output writer | ||
* @param value current parameter | ||
* @param value current parameter. Expected to be non-null | ||
* @param opts connection options | ||
@@ -32,8 +32,9 @@ * @param info connection information | ||
case 'number': | ||
out.writeStringAscii('' + value); | ||
out.writeStringAscii(`${value}`); | ||
break; | ||
case 'string': | ||
out.writeStringEscapeQuote(value); | ||
break; | ||
case 'object': | ||
if (value == null) { | ||
out.writeStringAscii('NULL'); | ||
} else if (value instanceof Date) { | ||
if (Object.prototype.toString.call(value) === '[object Date]') { | ||
out.writeStringAscii(TextEncoder.getLocalDate(value)); | ||
@@ -52,3 +53,5 @@ } else if (Buffer.isBuffer(value)) { | ||
if (i !== 0) out.writeStringAscii(','); | ||
TextEncoder.writeParam(out, value[i], opts, info); | ||
if (value[i] == null) { | ||
out.writeStringAscii('NULL'); | ||
} else TextEncoder.writeParam(out, value[i], opts, info); | ||
} | ||
@@ -134,2 +137,5 @@ if (opts.arrayParenthesis) { | ||
} | ||
} else if (String === value.constructor) { | ||
out.writeStringEscapeQuote(value); | ||
break; | ||
} else { | ||
@@ -147,4 +153,8 @@ if (opts.permitSetMultiParamEntries) { | ||
out.writeString('`' + key + '`'); | ||
out.writeStringAscii('='); | ||
TextEncoder.writeParam(out, val, opts, info); | ||
if (val == null) { | ||
out.writeStringAscii('=NULL'); | ||
} else { | ||
out.writeStringAscii('='); | ||
TextEncoder.writeParam(out, val, opts, info); | ||
} | ||
} | ||
@@ -158,8 +168,2 @@ if (first) out.writeStringEscapeQuote(JSON.stringify(value)); | ||
break; | ||
default: | ||
if (value == null) { | ||
out.writeStringAscii('NULL'); | ||
} else { | ||
out.writeStringEscapeQuote(value); | ||
} | ||
} | ||
@@ -255,3 +259,3 @@ } | ||
let res = '' + ms; | ||
let res = `${ms}`; | ||
while (res.length < 3) res = '0' + res; | ||
@@ -258,0 +262,0 @@ return d + '.' + res + "'"; |
@@ -19,3 +19,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
super(resolve, reject, connOpts, cmdParam); | ||
this.writeParam = BinaryEncoder.writeParam; | ||
this.binary = true; | ||
@@ -60,25 +59,105 @@ this.prepare = prepare; | ||
// send long data using COM_STMT_SEND_LONG_DATA | ||
this.longDataStep = false; // send long data | ||
// fill parameter data type | ||
this.parametersType = new Array(this.parameterCount); | ||
let hasLongData = false; // send long data | ||
let val; | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
const value = this.values[i]; | ||
val = this.values[i]; | ||
// special check for GEOJSON that can be null even if object is not | ||
if ( | ||
value != null && | ||
((typeof value === 'object' && typeof value.pipe === 'function' && typeof value.read === 'function') || | ||
(Buffer.isBuffer(value) && this.prepare)) | ||
val && | ||
val.type != null && | ||
[ | ||
'Point', | ||
'LineString', | ||
'Polygon', | ||
'MultiPoint', | ||
'MultiLineString', | ||
'MultiPolygon', | ||
'GeometryCollection' | ||
].includes(val.type) | ||
) { | ||
if (opts.logger.query) | ||
opts.logger.query( | ||
`EXECUTE: (${this.prepare ? this.prepare.id : -1}) sql: ${opts.logParam ? this.displaySql() : this.sql}` | ||
); | ||
if (!this.longDataStep) { | ||
this.longDataStep = true; | ||
this.registerStreamSendEvent(out, info); | ||
this.currentParam = i; | ||
const geoBuff = BinaryEncoder.getBufferFromGeometryValue(val); | ||
if (geoBuff == null) { | ||
this.values[i] = null; | ||
val = null; | ||
} else { | ||
this.values[i] = Buffer.concat([ | ||
Buffer.from([0, 0, 0, 0]), // SRID | ||
geoBuff // WKB | ||
]); | ||
val = this.values[i]; | ||
} | ||
this.sendComStmtLongData(out, info, value); | ||
return; | ||
} | ||
if (val == null) { | ||
this.parametersType[i] = NULL_PARAM_TYPE; | ||
} else { | ||
switch (typeof val) { | ||
case 'boolean': | ||
this.parametersType[i] = BOOLEAN_TYPE; | ||
break; | ||
case 'bigint': | ||
if (val >= 2n ** 63n) { | ||
this.parametersType[i] = BIG_BIGINT_TYPE; | ||
} else { | ||
this.parametersType[i] = BIGINT_TYPE; | ||
} | ||
break; | ||
case 'number': | ||
// additional verification, to permit query without type, | ||
// like 'SELECT ?' returning same type of value | ||
if (Number.isInteger(val) && val >= -2147483648 && val < 2147483647) { | ||
this.parametersType[i] = INT_TYPE; | ||
break; | ||
} | ||
this.parametersType[i] = DOUBLE_TYPE; | ||
break; | ||
case 'string': | ||
this.parametersType[i] = STRING_TYPE; | ||
break; | ||
case 'object': | ||
if (Object.prototype.toString.call(val) === '[object Date]') { | ||
this.parametersType[i] = DATE_TYPE; | ||
} else if (Buffer.isBuffer(val)) { | ||
if (val.length < 16384 || !this.prepare) { | ||
this.parametersType[i] = BLOB_TYPE; | ||
} else { | ||
this.parametersType[i] = LONGBLOB_TYPE; | ||
hasLongData = true; | ||
} | ||
} else if (typeof val.toSqlString === 'function') { | ||
this.parametersType[i] = STRING_FCT_TYPE; | ||
} else if (typeof val.pipe === 'function' && typeof val.read === 'function') { | ||
hasLongData = true; | ||
this.parametersType[i] = STREAM_TYPE; | ||
} else if (String === val.constructor) { | ||
this.parametersType[i] = STRING_TOSTR_TYPE; | ||
} else { | ||
this.parametersType[i] = STRINGIFY_TYPE; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
// send long data using COM_STMT_SEND_LONG_DATA | ||
this.longDataStep = false; // send long data | ||
if (hasLongData) { | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
if (this.parametersType[i].isLongData()) { | ||
if (opts.logger.query) | ||
opts.logger.query( | ||
`EXECUTE: (${this.prepare ? this.prepare.id : -1}) sql: ${opts.logParam ? this.displaySql() : this.sql}` | ||
); | ||
if (!this.longDataStep) { | ||
this.longDataStep = true; | ||
this.registerStreamSendEvent(out, info); | ||
this.currentParam = i; | ||
} | ||
this.sendComStmtLongData(out, info, this.values[i]); | ||
return; | ||
} | ||
} | ||
} | ||
if (!this.longDataStep) { | ||
@@ -113,37 +192,14 @@ // no stream parameter, so can send directly | ||
//validate parameter is defined. | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
if (this.opts.namedPlaceholders && this.placeHolderIndex && this.values[i] === undefined) { | ||
let errMsg = `Parameter named ${this.placeHolderIndex[i]} is not set`; | ||
if (this.placeHolderIndex.length < this.parameterCount) { | ||
errMsg = `Command expect ${this.parameterCount} parameters, but found only ${this.placeHolderIndex.length} named parameters. You probably use question mark in place of named parameters`; | ||
// validate placeholder | ||
if (this.opts.namedPlaceholders && this.placeHolderIndex) { | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
if (this.values[i] === undefined) { | ||
let errMsg = `Parameter named ${this.placeHolderIndex[i]} is not set`; | ||
if (this.placeHolderIndex.length < this.parameterCount) { | ||
errMsg = `Command expect ${this.parameterCount} parameters, but found only ${this.placeHolderIndex.length} named parameters. You probably use question mark in place of named parameters`; | ||
} | ||
this.sendCancelled(errMsg, Errors.ER_PARAMETER_UNDEFINED, info); | ||
return false; | ||
} | ||
this.sendCancelled(errMsg, Errors.ER_PARAMETER_UNDEFINED, info); | ||
return false; | ||
} | ||
// special check for GEOJSON that can be null even if object is not | ||
if ( | ||
this.values[i] && | ||
this.values[i].type != null && | ||
[ | ||
'Point', | ||
'LineString', | ||
'Polygon', | ||
'MultiPoint', | ||
'MultiLineString', | ||
'MultiPolygon', | ||
'GeometryCollection' | ||
].includes(this.values[i].type) | ||
) { | ||
const geoBuff = BinaryEncoder.getBufferFromGeometryValue(this.values[i]); | ||
if (geoBuff == null) { | ||
this.values[i] = null; | ||
} else { | ||
this.values[i] = Buffer.concat([ | ||
Buffer.from([0, 0, 0, 0]), // SRID | ||
geoBuff // WKB | ||
]); | ||
} | ||
} | ||
} | ||
@@ -188,7 +244,7 @@ return true; | ||
sendComStmtExecute(out, info) { | ||
let nullCount = Math.floor((this.parameterCount + 7) / 8); | ||
let nullCount = ~~((this.parameterCount + 7) / 8); | ||
const nullBitsBuffer = Buffer.alloc(nullCount); | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
if (this.values[i] == null) { | ||
nullBitsBuffer[Math.floor(i / 8)] |= 1 << i % 8; | ||
nullBitsBuffer[~~(i / 8)] |= 1 << i % 8; | ||
} | ||
@@ -207,47 +263,3 @@ } | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
const val = this.values[i]; | ||
if (val != null) { | ||
switch (typeof val) { | ||
case 'boolean': | ||
out.writeInt8(FieldType.TINY); | ||
break; | ||
case 'bigint': | ||
if (val >= 2n ** 63n) { | ||
out.writeInt8(FieldType.NEWDECIMAL); | ||
} else { | ||
out.writeInt8(FieldType.BIGINT); | ||
} | ||
break; | ||
case 'number': | ||
// additional verification, to permit query without type, | ||
// like 'SELECT ?' returning same type of value | ||
if (Number.isSafeInteger(val) && val >= -2147483648 && val < 2147483647) { | ||
out.writeInt8(FieldType.INT); | ||
break; | ||
} | ||
out.writeInt8(FieldType.DOUBLE); | ||
break; | ||
case 'string': | ||
out.writeInt8(FieldType.VAR_STRING); | ||
break; | ||
case 'object': | ||
if (val instanceof Date) { | ||
out.writeInt8(FieldType.DATETIME); | ||
} else if (Buffer.isBuffer(val)) { | ||
out.writeInt8(FieldType.BLOB); | ||
} else if (typeof val.toSqlString === 'function') { | ||
out.writeInt8(FieldType.VAR_STRING); | ||
} else if (typeof val.pipe === 'function' && typeof val.read === 'function') { | ||
out.writeInt8(FieldType.BLOB); | ||
} else { | ||
out.writeInt8(FieldType.VAR_STRING); | ||
} | ||
break; | ||
default: | ||
out.writeInt8(FieldType.BLOB); | ||
break; | ||
} | ||
} else { | ||
out.writeInt8(FieldType.VAR_STRING); | ||
} | ||
out.writeInt8(this.parametersType[i].type); | ||
out.writeInt8(0); | ||
@@ -260,10 +272,4 @@ } | ||
for (let i = 0; i < this.parameterCount; i++) { | ||
const value = this.values[i]; | ||
if ( | ||
value != null && | ||
!(typeof value === 'object' && typeof value.pipe === 'function' && typeof value.read === 'function') && | ||
!(Buffer.isBuffer(value) && this.prepare) | ||
) { | ||
this.writeParam(out, value, this.opts, info); | ||
} | ||
const parameterType = this.parametersType[i]; | ||
if (parameterType.encoder) parameterType.encoder(out, this.values[i]); | ||
} | ||
@@ -286,10 +292,4 @@ out.flush(); | ||
for (; this.currentParam < this.parameterCount; this.currentParam++) { | ||
const value = this.values[this.currentParam]; | ||
if ( | ||
(value != null && | ||
typeof value === 'object' && | ||
typeof value.pipe === 'function' && | ||
typeof value.read === 'function') || | ||
Buffer.isBuffer(value) | ||
) { | ||
if (this.parametersType[this.currentParam].isLongData()) { | ||
const value = this.values[this.currentParam]; | ||
this.sendComStmtLongData(out, info, value); | ||
@@ -309,2 +309,38 @@ return; | ||
class ParameterType { | ||
constructor(type, encoder, pipe = false, isNull = false) { | ||
this.pipe = pipe; | ||
this.type = type; | ||
this.encoder = encoder; | ||
this.isNull = isNull; | ||
} | ||
isLongData() { | ||
return this.encoder === null && !this.isNull; | ||
} | ||
} | ||
const NULL_PARAM_TYPE = new ParameterType(FieldType.VAR_STRING, null, false, true); | ||
const BOOLEAN_TYPE = new ParameterType(FieldType.TINY, (out, value) => out.writeInt8(value ? 0x01 : 0x00)); | ||
const BIG_BIGINT_TYPE = new ParameterType(FieldType.NEWDECIMAL, (out, value) => | ||
out.writeLengthEncodedString(value.toString()) | ||
); | ||
const BIGINT_TYPE = new ParameterType(FieldType.BIGINT, (out, value) => out.writeBigInt(value)); | ||
const INT_TYPE = new ParameterType(FieldType.INT, (out, value) => out.writeInt32(value)); | ||
const DOUBLE_TYPE = new ParameterType(FieldType.DOUBLE, (out, value) => out.writeDouble(value)); | ||
const STRING_TYPE = new ParameterType(FieldType.VAR_STRING, (out, value) => out.writeLengthEncodedString(value)); | ||
const STRING_TOSTR_TYPE = new ParameterType(FieldType.VAR_STRING, (out, value) => | ||
out.writeLengthEncodedString(value.toString()) | ||
); | ||
const DATE_TYPE = new ParameterType(FieldType.DATETIME, (out, value) => out.writeBinaryDate(value)); | ||
const BLOB_TYPE = new ParameterType(FieldType.BLOB, (out, value) => out.writeLengthEncodedBuffer(value)); | ||
const LONGBLOB_TYPE = new ParameterType(FieldType.BLOB, null); | ||
const STRING_FCT_TYPE = new ParameterType(FieldType.VAR_STRING, (out, value) => | ||
out.writeLengthEncodedString(String(value.toSqlString())) | ||
); | ||
const STREAM_TYPE = new ParameterType(FieldType.BLOB, null, true); | ||
const STRINGIFY_TYPE = new ParameterType(FieldType.VAR_STRING, (out, value) => | ||
out.writeLengthEncodedString(JSON.stringify(value)) | ||
); | ||
module.exports = Execute; |
@@ -127,4 +127,6 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
case 'redirect_url': | ||
mustRedirect = true; | ||
info.redirect(value, this.successEnd); | ||
if (value !== '') { | ||
mustRedirect = true; | ||
info.redirect(value, this.successEnd); | ||
} | ||
break; | ||
@@ -131,0 +133,0 @@ |
@@ -122,5 +122,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const affectedRows = packet.readUnsignedLength(); | ||
let insertId = packet.readSignedLengthBigInt(); | ||
let insertId = packet.readInsertId(); | ||
info.status = packet.readUInt16(); | ||
if (insertId != null && (this.opts.supportBigNumbers || this.opts.insertIdAsNumber)) { | ||
if (this.opts.supportBigNumbers || this.opts.insertIdAsNumber) { | ||
if (this.opts.insertIdAsNumber && this.opts.checkNumberRange && !Number.isSafeInteger(Number(insertId))) { | ||
@@ -171,4 +171,6 @@ this.onPacketReceive = info.status & ServerStatus.MORE_RESULTS_EXISTS ? this.readResponsePacket : null; | ||
case 'redirect_url': | ||
mustRedirect = true; | ||
info.redirect(value, this.okPacketSuccess.bind(this, okPacket, info)); | ||
if (value !== '') { | ||
mustRedirect = true; | ||
info.redirect(value, this.okPacketSuccess.bind(this, okPacket, info)); | ||
} | ||
break; | ||
@@ -175,0 +177,0 @@ |
@@ -78,3 +78,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
if (this.executeCommand) this.executeCommand.prepare = prepare; | ||
return this.successEnd(prepare); | ||
this.successEnd(prepare); | ||
} | ||
@@ -136,3 +136,3 @@ | ||
} | ||
return (this.onPacketReceive = this.skipEofPacket); | ||
this.onPacketReceive = this.skipEofPacket; | ||
} | ||
@@ -143,3 +143,3 @@ } | ||
if (this.columnNo > 0) return (this.onPacketReceive = this.readPrepareColumnsPacket); | ||
return this.successPrepare(info, opts); | ||
this.successPrepare(info, opts); | ||
} | ||
@@ -154,3 +154,3 @@ | ||
} | ||
return (this.onPacketReceive = this.skipEofPacket); | ||
this.onPacketReceive = this.skipEofPacket; | ||
} | ||
@@ -157,0 +157,0 @@ } |
@@ -20,3 +20,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
super(resolve, reject, connOpts, cmdParam); | ||
this.writeParam = TextEncoder.writeParam; | ||
this.binary = false; | ||
@@ -84,32 +83,164 @@ } | ||
const value = this.values[this.valueIdx++]; | ||
if (value == null) { | ||
out.writeStringAscii('NULL'); | ||
continue; | ||
} | ||
switch (typeof value) { | ||
case 'boolean': | ||
out.writeStringAscii(value ? 'true' : 'false'); | ||
break; | ||
case 'bigint': | ||
case 'number': | ||
out.writeStringAscii(`${value}`); | ||
break; | ||
case 'string': | ||
out.writeStringEscapeQuote(value); | ||
break; | ||
case 'object': | ||
if (typeof value.pipe === 'function' && typeof value.read === 'function') { | ||
this.sending = true; | ||
//******************************************** | ||
// param is stream, | ||
// now all params will be written by event | ||
//******************************************** | ||
this.paramWritten = this._paramWritten.bind(this, out, info); | ||
out.writeInt8(QUOTE); //' | ||
value.on('data', out.writeBufferEscape.bind(out)); | ||
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.paramWritten = this._paramWritten.bind(this, out, info); | ||
out.writeInt8(QUOTE); //' | ||
value.on('data', out.writeBufferEscape.bind(out)); | ||
value.on( | ||
'end', | ||
function () { | ||
out.writeInt8(QUOTE); //' | ||
this.paramWritten(); | ||
}.bind(this) | ||
); | ||
return; | ||
} | ||
value.on( | ||
'end', | ||
function () { | ||
out.writeInt8(QUOTE); //' | ||
this.paramWritten(); | ||
}.bind(this) | ||
); | ||
if (Object.prototype.toString.call(value) === '[object Date]') { | ||
out.writeStringAscii(TextEncoder.getLocalDate(value)); | ||
} 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 (Array.isArray(value)) { | ||
if (opts.arrayParenthesis) { | ||
out.writeStringAscii('('); | ||
} | ||
for (let i = 0; i < value.length; i++) { | ||
if (i !== 0) out.writeStringAscii(','); | ||
if (value[i] == null) { | ||
out.writeStringAscii('NULL'); | ||
} else TextEncoder.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(" + TextEncoder.geoPointToString(value.coordinates) + ")')" | ||
); | ||
break; | ||
return; | ||
} else { | ||
//******************************************** | ||
// param isn't stream. directly write in buffer | ||
//******************************************** | ||
this.writeParam(out, value, this.opts, info); | ||
case 'LineString': | ||
out.writeStringAscii( | ||
prefix + "LineFromText('LINESTRING(" + TextEncoder.geoArrayPointToString(value.coordinates) + ")')" | ||
); | ||
break; | ||
case 'Polygon': | ||
out.writeStringAscii( | ||
prefix + | ||
"PolygonFromText('POLYGON(" + | ||
TextEncoder.geoMultiArrayPointToString(value.coordinates) + | ||
")')" | ||
); | ||
break; | ||
case 'MultiPoint': | ||
out.writeStringAscii( | ||
prefix + | ||
"MULTIPOINTFROMTEXT('MULTIPOINT(" + | ||
TextEncoder.geoArrayPointToString(value.coordinates) + | ||
")')" | ||
); | ||
break; | ||
case 'MultiLineString': | ||
out.writeStringAscii( | ||
prefix + | ||
"MLineFromText('MULTILINESTRING(" + | ||
TextEncoder.geoMultiArrayPointToString(value.coordinates) + | ||
")')" | ||
); | ||
break; | ||
case 'MultiPolygon': | ||
out.writeStringAscii( | ||
prefix + | ||
"MPolyFromText('MULTIPOLYGON(" + | ||
TextEncoder.geoMultiPolygonToString(value.coordinates) + | ||
")')" | ||
); | ||
break; | ||
case 'GeometryCollection': | ||
out.writeStringAscii( | ||
prefix + | ||
"GeomCollFromText('GEOMETRYCOLLECTION(" + | ||
TextEncoder.geometricCollectionToString(value.geometries) + | ||
")')" | ||
); | ||
break; | ||
} | ||
} else if (String === value.constructor) { | ||
out.writeStringEscapeQuote(value); | ||
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 + '`'); | ||
if (val == null) { | ||
out.writeStringAscii('=NULL'); | ||
} else { | ||
out.writeStringAscii('='); | ||
TextEncoder.writeParam(out, val, opts, info); | ||
} | ||
} | ||
if (first) out.writeStringEscapeQuote(JSON.stringify(value)); | ||
} else { | ||
out.writeStringEscapeQuote(JSON.stringify(value)); | ||
} | ||
} | ||
} | ||
break; | ||
} | ||
@@ -216,3 +347,3 @@ } | ||
//******************************************** | ||
this.writeParam(out, value, this.opts, info); | ||
TextEncoder.writeParam(out, value, this.opts, info); | ||
} | ||
@@ -219,0 +350,0 @@ } |
@@ -9,3 +9,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const Query = require('./cmd/query'); | ||
const CommandParameter = require('./command-parameter'); | ||
@@ -52,3 +51,6 @@ class ConnectionCallback { | ||
} | ||
const cmdParam = new CommandParameter(null, null, _options, _cb); | ||
const cmdParam = { | ||
opts: _options, | ||
callback: _cb | ||
}; | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
@@ -69,3 +71,3 @@ | ||
beginTransaction(callback) { | ||
this.query(new CommandParameter('START TRANSACTION'), null, callback); | ||
this.query('START TRANSACTION', null, callback); | ||
} | ||
@@ -80,3 +82,3 @@ | ||
this.#conn.changeTransaction( | ||
new CommandParameter('COMMIT'), | ||
{ sql: 'COMMIT' }, | ||
() => { | ||
@@ -96,3 +98,3 @@ if (callback) callback(null, null, null); | ||
this.#conn.changeTransaction( | ||
new CommandParameter('ROLLBACK'), | ||
{ sql: 'ROLLBACK' }, | ||
() => { | ||
@@ -145,3 +147,3 @@ if (callback) callback(null, null, null); | ||
conn.addCommand(cmd); | ||
conn.addCommand(cmd, true); | ||
cmd.stream = (opt) => cmd._stream(conn.socket, opt); | ||
@@ -184,3 +186,9 @@ return cmd; | ||
} | ||
const cmdParam = new CommandParameter(_sql, _values, _cmdOpt, _cb); | ||
const cmdParam = { | ||
sql: _sql, | ||
values: _values, | ||
opts: _cmdOpt, | ||
callback: _cb | ||
}; | ||
if (options.trace) Error.captureStackTrace(cmdParam, ConnectionCallback._PARAM); | ||
@@ -217,3 +225,7 @@ return cmdParam; | ||
} | ||
const cmdParam = new CommandParameter(_sql, null, _cmdOpt, callback); | ||
const cmdParam = { | ||
sql: _sql, | ||
opts: _cmdOpt, | ||
callback: callback | ||
}; | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
@@ -297,3 +309,6 @@ return new Promise(this.#conn.prepare.bind(this.#conn, cmdParam)) | ||
} | ||
const cmdParam = new CommandParameter(null, null, _cmdOpt, _cb); | ||
const cmdParam = { | ||
opts: _cmdOpt, | ||
callback: _cb | ||
}; | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
@@ -315,3 +330,3 @@ new Promise(this.#conn.ping.bind(this.#conn, cmdParam)).then(_cb || this.#noop).catch(_cb || this.#noop); | ||
reset(callback) { | ||
const cmdParam = new CommandParameter(); | ||
const cmdParam = {}; | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
@@ -337,3 +352,3 @@ return new Promise(this.#conn.reset.bind(this.#conn, cmdParam)) | ||
end(callback) { | ||
const cmdParam = new CommandParameter(); | ||
const cmdParam = {}; | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
@@ -340,0 +355,0 @@ new Promise(this.#conn.end.bind(this.#conn, cmdParam)) |
@@ -7,3 +7,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const Stream = require('./cmd/stream'); | ||
const CommandParameter = require('./command-parameter'); | ||
const Errors = require('./misc/errors'); | ||
@@ -24,5 +23,7 @@ | ||
#conn; | ||
#capture; | ||
constructor(conn) { | ||
this.#conn = conn; | ||
this.#capture = conn.opts.trace ? Error.captureStackTrace : () => {}; | ||
} | ||
@@ -51,5 +52,5 @@ | ||
changeUser(options) { | ||
const cmdParam = new CommandParameter(null, null, options); | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
return new Promise(this.#conn.changeUser.bind(this.#conn, cmdParam)); | ||
const param = { opts: options }; | ||
this.#capture(param); | ||
return new Promise(this.#conn.changeUser.bind(this.#conn, param)); | ||
} | ||
@@ -63,3 +64,5 @@ | ||
beginTransaction() { | ||
return this.query('START TRANSACTION'); | ||
const param = { sql: 'START TRANSACTION' }; | ||
this.#capture(param); | ||
return new Promise(this.#conn.query.bind(this.#conn, param)); | ||
} | ||
@@ -73,4 +76,5 @@ | ||
commit() { | ||
const cmdParam = ConnectionPromise._PARAM(this.#conn.opts, 'COMMIT'); | ||
return new Promise(this.#conn.changeTransaction.bind(this.#conn, cmdParam)); | ||
const param = { sql: 'COMMIT' }; | ||
this.#capture(param); | ||
return new Promise(this.#conn.changeTransaction.bind(this.#conn, param)); | ||
} | ||
@@ -84,4 +88,5 @@ | ||
rollback() { | ||
const cmdParam = ConnectionPromise._PARAM(this.#conn.opts, 'ROLLBACK'); | ||
return new Promise(this.#conn.changeTransaction.bind(this.#conn, cmdParam)); | ||
const param = { sql: 'ROLLBACK' }; | ||
this.#capture(param); | ||
return new Promise(this.#conn.changeTransaction.bind(this.#conn, param)); | ||
} | ||
@@ -98,22 +103,16 @@ | ||
query(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#conn.opts, sql, values); | ||
const cmdParam = paramSetter(sql, values); | ||
this.#capture(cmdParam); | ||
return new Promise(this.#conn.query.bind(this.#conn, cmdParam)); | ||
} | ||
static _PARAM(options, sql, values) { | ||
let _cmdOpt, | ||
_sql = sql, | ||
_values = values; | ||
static _PARAM_DEF(sql, values) { | ||
if (typeof sql === 'object') { | ||
_cmdOpt = sql; | ||
_sql = _cmdOpt.sql; | ||
if (_cmdOpt.values) _values = _cmdOpt.values; | ||
} | ||
const cmdParam = new CommandParameter(_sql, _values, _cmdOpt); | ||
if (options.trace) Error.captureStackTrace(cmdParam, ConnectionPromise._PARAM); | ||
return cmdParam; | ||
return { sql: sql.sql, values: sql.values ? sql.values : values, opts: sql }; | ||
} else return { sql: sql, values: values }; | ||
} | ||
execute(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#conn.opts, sql, values); | ||
const cmdParam = paramSetter(sql, values); | ||
this.#capture(cmdParam); | ||
return this.#conn.prepareExecute(cmdParam); | ||
@@ -127,12 +126,10 @@ } | ||
prepare(sql) { | ||
let _cmdOpt, _sql; | ||
let param; | ||
if (typeof sql === 'object') { | ||
_cmdOpt = sql; | ||
_sql = _cmdOpt.sql; | ||
param = { sql: sql.sql, opts: sql }; | ||
} else { | ||
_sql = sql; | ||
param = { sql: sql }; | ||
} | ||
const cmdParam = new CommandParameter(_sql, null, _cmdOpt); | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
return new Promise(this.#conn.prepare.bind(this.#conn, cmdParam)); | ||
this.#capture(param); | ||
return new Promise(this.#conn.prepare.bind(this.#conn, param)); | ||
} | ||
@@ -149,3 +146,4 @@ | ||
batch(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#conn.opts, sql, values); | ||
const cmdParam = paramSetter(sql, values); | ||
this.#capture(cmdParam); | ||
return this.#conn.batch(cmdParam); | ||
@@ -190,6 +188,7 @@ } | ||
queryStream(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#conn.opts, sql, values); | ||
const cmdParam = paramSetter(sql, values); | ||
this.#capture(cmdParam); | ||
const cmd = new Stream(cmdParam, this.#conn.opts, this.#conn.socket); | ||
if (this.#conn.opts.logger.error) cmd.on('error', this.#conn.opts.logger.error); | ||
this.#conn.addCommand(cmd); | ||
this.#conn.addCommand(cmd, true); | ||
return cmd.inStream; | ||
@@ -204,4 +203,6 @@ } | ||
ping(timeout) { | ||
const cmdParam = new CommandParameter(null, null, { timeout: timeout }); | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
const cmdParam = { | ||
opts: { timeout: timeout } | ||
}; | ||
this.#capture(cmdParam); | ||
return new Promise(this.#conn.ping.bind(this.#conn, cmdParam)); | ||
@@ -222,4 +223,4 @@ } | ||
reset() { | ||
const cmdParam = new CommandParameter(); | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
const cmdParam = {}; | ||
this.#capture(cmdParam); | ||
return new Promise(this.#conn.reset.bind(this.#conn, cmdParam)); | ||
@@ -242,4 +243,4 @@ } | ||
end() { | ||
const cmdParam = new CommandParameter(); | ||
if (this.#conn.opts.trace) Error.captureStackTrace(cmdParam); | ||
const cmdParam = {}; | ||
this.#capture(cmdParam); | ||
return new Promise(this.#conn.end.bind(this.#conn, cmdParam)); | ||
@@ -381,2 +382,9 @@ } | ||
const paramSetter = function (sql, values) { | ||
if (typeof sql === 'object') { | ||
return { sql: sql.sql, values: sql.values ? sql.values : values, opts: sql }; | ||
} else return { sql: sql, values: values }; | ||
}; | ||
module.exports = ConnectionPromise; | ||
module.exports.paramSetter = paramSetter; |
@@ -34,3 +34,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const { Status } = require('./const/connection_status'); | ||
const CommandParameter = require('./command-parameter'); | ||
const LruPrepareCache = require('./lru-prepare-cache'); | ||
@@ -130,3 +129,5 @@ const fsPromises = require('fs').promises; | ||
this.status = Status.CONNECTING; | ||
const authenticationParam = new CommandParameter(null, null, this.opts, null); | ||
const authenticationParam = { | ||
opts: this.opts | ||
}; | ||
return new Promise(function (resolve, reject) { | ||
@@ -162,3 +163,3 @@ conn.connectRejectFct = reject; | ||
const cmd = new Execute(resolve, this._logAndReject.bind(this, reject), this.opts, cmdParam, prepare); | ||
this.addCommand(cmd); | ||
this.addCommand(cmd, true); | ||
} | ||
@@ -292,3 +293,3 @@ | ||
); | ||
this.addCommand(cmd); | ||
this.addCommand(cmd, true); | ||
} | ||
@@ -347,7 +348,8 @@ | ||
} | ||
) | ||
), | ||
true | ||
); | ||
return; | ||
} | ||
this.addCommand(new Ping(cmdParam, resolve, reject)); | ||
this.addCommand(new Ping(cmdParam, resolve, reject), true); | ||
} | ||
@@ -373,3 +375,3 @@ | ||
() => { | ||
conn.prepareCache.reset(); | ||
if (conn.prepareCache) conn.prepareCache.reset(); | ||
let prom = Promise.resolve(); | ||
@@ -387,3 +389,3 @@ // re-execute init query / session query timeout | ||
); | ||
this.addCommand(resetCmd); | ||
this.addCommand(resetCmd, true); | ||
return; | ||
@@ -664,3 +666,8 @@ } | ||
return new Promise(this.query.bind(this, new CommandParameter(sessionQuery, values))).catch((initialErr) => { | ||
return new Promise( | ||
this.query.bind(this, { | ||
sql: sessionQuery, | ||
values: values | ||
}) | ||
).catch((initialErr) => { | ||
const err = Errors.createFatalError( | ||
@@ -697,3 +704,5 @@ `Error setting session variable (value ${JSON.stringify(this.opts.sessionVariables)}). Error: ${ | ||
return new Promise( | ||
this.query.bind(this, new CommandParameter(`SET NAMES ${charset} COLLATE ${this.opts.collation.name}`)) | ||
this.query.bind(this, { | ||
sql: `SET NAMES ${charset} COLLATE ${this.opts.collation.name}` | ||
}) | ||
); | ||
@@ -715,3 +724,7 @@ } | ||
this.info.collation = Collations.fromCharset(connCharset); | ||
return new Promise(this.query.bind(this, new CommandParameter(`SET NAMES ${connCharset}`))); | ||
return new Promise( | ||
this.query.bind(this, { | ||
sql: `SET NAMES ${connCharset}` | ||
}) | ||
); | ||
} | ||
@@ -729,3 +742,5 @@ | ||
return new Promise( | ||
this.query.bind(this, new CommandParameter('SELECT @@system_time_zone stz, @@time_zone tz')) | ||
this.query.bind(this, { | ||
sql: 'SELECT @@system_time_zone stz, @@time_zone tz' | ||
}) | ||
).then((res) => { | ||
@@ -750,3 +765,8 @@ const serverTimezone = res[0].tz === 'SYSTEM' ? res[0].stz : res[0].tz; | ||
_setSessionTimezone(tz) { | ||
return new Promise(this.query.bind(this, new CommandParameter('SET time_zone=?', [tz]))).catch((err) => { | ||
return new Promise( | ||
this.query.bind(this, { | ||
sql: 'SET time_zone=?', | ||
values: [tz] | ||
}) | ||
).catch((err) => { | ||
const er = Errors.createFatalError( | ||
@@ -766,3 +786,7 @@ `setting timezone '${tz}' fails on server.\n look at https://mariadb.com/kb/en/mysql_tzinfo_to_sql/ to load IANA timezone. `, | ||
} | ||
return new Promise(this.query.bind(this, new CommandParameter('SELECT @@VERSION AS v'))).then( | ||
return new Promise( | ||
this.query.bind(this, { | ||
sql: 'SELECT @@VERSION AS v' | ||
}) | ||
).then( | ||
function (res) { | ||
@@ -782,3 +806,9 @@ this.info.serverVersion.raw = res[0].v; | ||
initialArr.forEach((sql) => { | ||
initialPromises.push(new Promise(this.query.bind(this, new CommandParameter(sql)))); | ||
initialPromises.push( | ||
new Promise( | ||
this.query.bind(this, { | ||
sql: sql | ||
}) | ||
) | ||
); | ||
}); | ||
@@ -803,3 +833,7 @@ | ||
const query = `SET max_statement_time=${this.opts.queryTimeout / 1000}`; | ||
new Promise(this.query.bind(this, new CommandParameter(query))).catch( | ||
new Promise( | ||
this.query.bind(this, { | ||
sql: query | ||
}) | ||
).catch( | ||
function (initialErr) { | ||
@@ -944,3 +978,3 @@ const err = Errors.createFatalError( | ||
commands.forEach((cmd) => { | ||
conn.addCommand(cmd); | ||
conn.addCommand(cmd, true); | ||
}); | ||
@@ -1099,5 +1133,6 @@ conn.waitingAuthenticationQueue = null; | ||
* @param cmd command | ||
* @param expectResponse queue command response | ||
* @private | ||
*/ | ||
addCommandEnable(cmd) { | ||
addCommandEnable(cmd, expectResponse) { | ||
cmd.once('end', this._sendNextCmdImmediate.bind(this)); | ||
@@ -1107,6 +1142,6 @@ | ||
if (this.sendQueue.isEmpty() && this.receiveQueue.isEmpty()) { | ||
this.receiveQueue.push(cmd); | ||
if (expectResponse) this.receiveQueue.push(cmd); | ||
cmd.start(this.streamOut, this.opts, this.info); | ||
} else { | ||
this.receiveQueue.push(cmd); | ||
if (expectResponse) this.receiveQueue.push(cmd); | ||
this.sendQueue.push(cmd); | ||
@@ -1119,9 +1154,10 @@ } | ||
* | ||
* @param cmd command | ||
* @param cmd command | ||
* @param expectResponse queue command response | ||
* @private | ||
*/ | ||
addCommandEnablePipeline(cmd) { | ||
addCommandEnablePipeline(cmd, expectResponse) { | ||
cmd.once('send_end', this._sendNextCmdImmediate.bind(this)); | ||
this.receiveQueue.push(cmd); | ||
if (expectResponse) this.receiveQueue.push(cmd); | ||
if (this.sendQueue.isEmpty()) { | ||
@@ -1310,3 +1346,3 @@ cmd.start(this.streamOut, this.opts, this.info); | ||
); | ||
this.addCommand(cmd); | ||
this.addCommand(cmd, true); | ||
} else resolve(); | ||
@@ -1365,3 +1401,4 @@ } | ||
this.getSocket.bind(this) | ||
) | ||
), | ||
true | ||
); | ||
@@ -1392,3 +1429,3 @@ } | ||
); | ||
this.addCommand(cmd); | ||
this.addCommand(cmd, true); | ||
} | ||
@@ -1417,3 +1454,3 @@ | ||
); | ||
this.addCommand(cmd); | ||
this.addCommand(cmd, true); | ||
} | ||
@@ -1492,4 +1529,4 @@ | ||
); | ||
conn.addCommand(cmd); | ||
conn.addCommand(executeCommand); | ||
conn.addCommand(cmd, true); | ||
conn.addCommand(executeCommand, true); | ||
}); | ||
@@ -1501,3 +1538,3 @@ } | ||
const cmd = new Prepare(resolve, reject, this.opts, cmdParam, conn); | ||
conn.addCommand(cmd); | ||
conn.addCommand(cmd, true); | ||
}) | ||
@@ -1542,5 +1579,8 @@ .then((prepare) => { | ||
conn.opts, | ||
new CommandParameter(sql, null, {}) | ||
{ | ||
sql: sql, | ||
opts: {} | ||
} | ||
); | ||
prevAddCommand(cmd); | ||
prevAddCommand(cmd, true); | ||
}; | ||
@@ -1580,3 +1620,3 @@ | ||
const commands = conn.waitingAuthenticationQueue.toArray(); | ||
commands.forEach((cmd) => conn.addCommand(cmd)); | ||
commands.forEach((cmd) => conn.addCommand(cmd, true)); | ||
conn.waitingAuthenticationQueue = null; | ||
@@ -1766,4 +1806,3 @@ } | ||
async function () { | ||
const cmdParam = new CommandParameter(); | ||
await new Promise(this.end.bind(this, cmdParam)); | ||
await new Promise(this.end.bind(this, {})); | ||
this.status = Status.CONNECTED; | ||
@@ -1812,7 +1851,8 @@ this.info = conn.info; | ||
new ClosePrepare( | ||
new CommandParameter(null, null, null, null), | ||
{}, | ||
() => {}, | ||
() => {}, | ||
prepareResultPacket | ||
) | ||
), | ||
false | ||
); | ||
@@ -1819,0 +1859,0 @@ } |
@@ -24,4 +24,4 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
readString(buf, beg, len) { | ||
return buf.toString(this.encoding, beg, beg + len); | ||
static readString(encoding, buf, beg, len) { | ||
return buf.toString(encoding, beg, beg + len); | ||
} | ||
@@ -28,0 +28,0 @@ |
@@ -23,4 +23,4 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
readString(buf, beg, len) { | ||
return Iconv.decode(buf.subarray(beg, beg + len), this.encoding); | ||
static readString(encoding, buf, beg, len) { | ||
return Iconv.decode(buf.subarray(beg, beg + len), encoding); | ||
} | ||
@@ -27,0 +27,0 @@ |
@@ -40,3 +40,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
this.buf = Buffer.allocUnsafe(SMALL_BUFFER_SIZE); | ||
this.maxAllowedPacket = opts.maxAllowedPacket || 4194304; | ||
this.maxAllowedPacket = opts.maxAllowedPacket || 16777216; | ||
this.maxPacketLength = Math.min(MAX_BUFFER_SIZE, this.maxAllowedPacket + 4); | ||
@@ -89,2 +89,6 @@ | ||
newCapacity = BIG_BUFFER_SIZE; | ||
} else if (this.bufContainDataAfterMark) { | ||
// special case, for bulk, when bunch of parameter doesn't fit in 16Mb packet | ||
// this save bunch of encoded parameter, sending parameter until mark, then resending data after mark | ||
newCapacity = len + this.pos; | ||
} else { | ||
@@ -103,3 +107,3 @@ newCapacity = MAX_BUFFER_SIZE; | ||
} | ||
this.growBuffer(len); | ||
return this.growBuffer(len); | ||
} | ||
@@ -323,4 +327,4 @@ } | ||
} else { | ||
for (let i = 0; i < len; i++) { | ||
this.buf[this.pos++] = arr[off + i]; | ||
for (let i = 0; i < len; ) { | ||
this.buf[this.pos++] = arr[off + i++]; | ||
} | ||
@@ -634,5 +638,5 @@ } | ||
checkMaxAllowedLength(length, info) { | ||
if (this.cmdLength + length >= this.maxAllowedPacket) { | ||
if (this.opts.maxAllowedPacket && this.cmdLength + length >= this.maxAllowedPacket) { | ||
// launch exception only if no packet has been sent. | ||
return Errors.createFatalError( | ||
return Errors.createError( | ||
`query size (${this.cmdLength + length}) is >= to max_allowed_packet (${this.maxAllowedPacket})`, | ||
@@ -639,0 +643,0 @@ Errors.ER_MAX_ALLOWED_PACKET, |
@@ -249,13 +249,16 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
readSignedLengthBigInt() { | ||
/** | ||
* Return unsigned Bigint. | ||
* | ||
* Could be used for reading other kind of value than InsertId, if reading possible null value | ||
* @returns {bigint} | ||
*/ | ||
readInsertId() { | ||
const type = this.buf[this.pos++]; | ||
if (type < 0xfb) return BigInt(type); | ||
switch (type) { | ||
// null test is not used for now, since only used for reading insertId | ||
// case 0xfb: | ||
// return null; | ||
case 0xfc: | ||
return BigInt(this.readUInt16()); | ||
return BigInt(this.buf[this.pos++] + this.buf[this.pos++] * 2 ** 8); | ||
case 0xfd: | ||
return BigInt(this.readUInt24()); | ||
return BigInt(this.buf[this.pos++] + this.buf[this.pos++] * 2 ** 8 + this.buf[this.pos++] * 2 ** 16); | ||
case 0xfe: | ||
@@ -262,0 +265,0 @@ return this.readBigInt64(); |
@@ -115,3 +115,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const escapeParameters = (opts, info, value) => { | ||
if (value === undefined || value === null) return 'NULL'; | ||
if (value == null) return 'NULL'; | ||
@@ -123,5 +123,5 @@ switch (typeof value) { | ||
case 'number': | ||
return '' + value; | ||
return `${value}`; | ||
case 'object': | ||
if (value instanceof Date) { | ||
if (Object.prototype.toString.call(value) === '[object Date]') { | ||
return TextEncoder.getFixedFormatDate(value); | ||
@@ -128,0 +128,0 @@ } else if (Buffer.isBuffer(value)) { |
@@ -11,3 +11,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const ConnectionCallback = require('./connection-callback'); | ||
const CommandParameter = require('./command-parameter'); | ||
@@ -97,3 +96,3 @@ class PoolCallback extends EventEmitter { | ||
} | ||
const cmdParam = new CommandParameter(); | ||
const cmdParam = {}; | ||
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam); | ||
@@ -228,4 +227,7 @@ this.#pool | ||
} | ||
toString() { | ||
return 'poolCallback(' + this.#pool.toString() + ')'; | ||
} | ||
} | ||
module.exports = PoolCallback; |
@@ -10,3 +10,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const ConnectionPromise = require('./connection-promise'); | ||
const CommandParameter = require('./command-parameter'); | ||
const Errors = require('./misc/errors'); | ||
@@ -86,3 +85,3 @@ | ||
async getConnection() { | ||
const cmdParam = new CommandParameter(); | ||
const cmdParam = {}; | ||
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam); | ||
@@ -106,3 +105,4 @@ const baseConn = await this.#pool.getConnection(cmdParam); | ||
query(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#pool.opts.connOptions, sql, values); | ||
const cmdParam = ConnectionPromise.paramSetter(sql, values); | ||
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam); | ||
return this.#pool.getConnection(cmdParam).then((baseConn) => { | ||
@@ -124,3 +124,4 @@ return new Promise(baseConn.query.bind(baseConn, cmdParam)).finally(() => { | ||
execute(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#pool.opts.connOptions, sql, values); | ||
const cmdParam = ConnectionPromise.paramSetter(sql, values); | ||
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam); | ||
return this.#pool.getConnection(cmdParam).then((baseConn) => { | ||
@@ -141,3 +142,4 @@ return ConnectionPromise._EXECUTE_CMD(baseConn, cmdParam).finally(() => { | ||
batch(sql, values) { | ||
const cmdParam = ConnectionPromise._PARAM(this.#pool.opts.connOptions, sql, values); | ||
const cmdParam = ConnectionPromise.paramSetter(sql, values); | ||
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam); | ||
return this.#pool.getConnection(cmdParam).then((baseConn) => { | ||
@@ -178,4 +180,8 @@ return ConnectionPromise._BATCH_CMD(baseConn, cmdParam).finally(() => { | ||
} | ||
toString() { | ||
return 'poolPromise(' + this.#pool.toString() + ')'; | ||
} | ||
} | ||
module.exports = PoolPromise; |
@@ -12,3 +12,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const Connection = require('./connection'); | ||
const CommandParameter = require('./command-parameter'); | ||
@@ -43,3 +42,3 @@ class Pool extends EventEmitter { | ||
_doCreateConnection(resolve, reject, timeoutEnd) { | ||
this._createConnection() | ||
this._createConnection(timeoutEnd) | ||
.then((conn) => { | ||
@@ -328,3 +327,5 @@ if (this.#closed) { | ||
try { | ||
const cmdParam = new CommandParameter(null, null, { timeout: this.opts.pingTimeout }); | ||
const cmdParam = { | ||
opts: { timeout: this.opts.pingTimeout } | ||
}; | ||
await new Promise(conn.ping.bind(conn, cmdParam)); | ||
@@ -401,4 +402,10 @@ } catch (e) { | ||
async _createConnection() { | ||
const conn = new Connection(this.opts.connOptions); | ||
async _createConnection(timeoutEnd) { | ||
// ensure setting a connection timeout if no connection timeout is set | ||
const minTimeout = Math.max(1, timeoutEnd - 100); | ||
const connectionOpts = | ||
!this.opts.connOptions.connectTimeout || this.opts.connOptions.connectTimeout > minTimeout | ||
? Object.assign({}, this.opts.connOptions, { connectTimeout: minTimeout }) | ||
: this.opts.connOptions; | ||
const conn = new Connection(connectionOpts); | ||
await conn.connect(); | ||
@@ -429,4 +436,4 @@ const pool = this; | ||
) { | ||
revertFunction = conn.reset.bind(conn, new CommandParameter()); | ||
} else revertFunction = conn.changeTransaction.bind(conn, new CommandParameter('ROLLBACK')); | ||
revertFunction = conn.reset.bind(conn, {}); | ||
} else revertFunction = conn.changeTransaction.bind(conn, { sql: 'ROLLBACK' }); | ||
@@ -458,2 +465,6 @@ new Promise(revertFunction).then(pool.release.bind(pool, conn), pool._destroy.bind(pool, conn)).finally(resolve); | ||
toString() { | ||
return `active=${this.activeConnections()} idle=${this.idleConnections()} limit=${this.opts.connectionLimit}`; | ||
} | ||
//***************************************************************** | ||
@@ -589,3 +600,3 @@ // public methods | ||
clearInterval(this._sizeHandlerTimeout); | ||
const cmdParam = new CommandParameter(); | ||
const cmdParam = {}; | ||
if (this.opts.trace) Error.captureStackTrace(cmdParam); | ||
@@ -592,0 +603,0 @@ //close unused connections |
{ | ||
"name": "mariadb", | ||
"version": "3.3.0", | ||
"version": "3.3.1", | ||
"description": "fast mariadb or mysql connector.", | ||
@@ -5,0 +5,0 @@ "main": "promise.js", |
@@ -16,3 +16,2 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
const ClusterOptions = require('./lib/config/cluster-options'); | ||
const CommandParameter = require('./lib/command-parameter'); | ||
@@ -69,3 +68,3 @@ module.exports.version = require('./package.json').version; | ||
.finally(() => { | ||
new Promise(conn.end.bind(conn, new CommandParameter())).catch(console.log); | ||
new Promise(conn.end.bind(conn, {})).catch(console.log); | ||
}); | ||
@@ -72,0 +71,0 @@ } catch (err) { |
@@ -661,3 +661,3 @@ // SPDX-License-Identifier: LGPL-2.1-or-later | ||
*/ | ||
prepare(sql: string): Promise<Prepare>; | ||
prepare(sql: string | QueryOptions): Promise<Prepare>; | ||
@@ -664,0 +664,0 @@ /** |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
656737
16610
73