Skip to content

Commit

Permalink
misc - set parser function once per result-set
Browse files Browse the repository at this point in the history
  • Loading branch information
diego Dupin committed Dec 13, 2021
1 parent 90bc00c commit 3f9b877
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 159 deletions.
180 changes: 79 additions & 101 deletions lib/cmd/column-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const Capabilities = require('../const/capabilities');
* see https://mariadb.com/kb/en/library/resultset/#column-definition-packet
*/
class ColumnDef {
constructor(packet, info, opts, binary) {
this._parse = new StringParser(packet);
constructor(packet, info) {
this._stringParser = new StringParser(packet);
if (info.serverCapabilities & Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO) {
const subPacket = packet.subPacketLengthEncoded();
while (subPacket.remaining()) {
Expand Down Expand Up @@ -43,31 +43,31 @@ class ColumnDef {
this.flags = packet.readUInt16();
this.scale = packet.readUInt8();
this.type = FieldType.TYPES[this.columnType];
}

__parser(binary, opts) {
// set reader function read(packet, index, nullBitmap, opts)
// this permit for multi-row result-set to avoid resolving type parsing each data.
if (binary) {
switch (this.columnType) {
case FieldType.TINY:
if (this.signed()) {
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readInt8());
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readInt8());
} else {
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readUInt8());
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readUInt8());
}
break;

case FieldType.YEAR:
case FieldType.SHORT:
if (this.signed()) {
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readInt16());
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readInt16());
} else {
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readUInt16());
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readUInt16());
}
break;

case FieldType.INT24:
if (this.signed()) {
this._read = (packet, index, nullBitmap) => {
return (packet, index, nullBitmap, opts) => {
if (isNullBitmap(index, nullBitmap)) {
return null;
}
Expand All @@ -76,7 +76,7 @@ class ColumnDef {
return result;
};
} else {
this._read = (packet, index, nullBitmap) => {
return (packet, index, nullBitmap, opts) => {
if (isNullBitmap(index, nullBitmap)) {
return null;
}
Expand All @@ -85,26 +85,22 @@ class ColumnDef {
return result;
};
}
break;

case FieldType.INT:
if (this.signed()) {
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readInt32());
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readInt32());
} else {
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readUInt32());
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readUInt32());
}
break;

case FieldType.FLOAT:
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readFloat());
break;
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readFloat());

case FieldType.DOUBLE:
this._read = (packet, index, nullBitmap) => (isNullBitmap(index, nullBitmap) ? null : packet.readDouble());
break;
return (packet, index, nullBitmap, opts) => (isNullBitmap(index, nullBitmap) ? null : packet.readDouble());

case FieldType.BIGINT:
this._read = (packet, index, nullBitmap, opts) => {
return (packet, index, nullBitmap, opts) => {
if (isNullBitmap(index, nullBitmap)) return null;
const val = this.signed() ? packet.readBigInt64() : packet.readBigUInt64();
if (val != null && (opts.bigIntAsNumber || opts.supportBigNumbers)) {
Expand All @@ -115,11 +111,23 @@ class ColumnDef {
}
return val;
};
break;

case FieldType.DATE:
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDate(opts);

case FieldType.DATETIME:
case FieldType.TIMESTAMP:
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDateTime(opts, this);

case FieldType.TIME:
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBinaryTime();

case FieldType.DECIMAL:
case FieldType.NEWDECIMAL:
this._read = (packet, index, nullBitmap, opts) => {
return (packet, index, nullBitmap, opts) => {
if (isNullBitmap(index, nullBitmap)) return null;
const valDec = packet.readDecimalLengthEncoded();
if (valDec != null && (opts.decimalAsNumber || opts.supportBigNumbers)) {
Expand All @@ -130,81 +138,41 @@ class ColumnDef {
}
return valDec;
};
break;

case FieldType.DATE:
this._read = (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDate(opts);
break;

case FieldType.DATETIME:
case FieldType.TIMESTAMP:
this._read = (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBinaryDateTime(opts, this);
break;

case FieldType.TIME:
this._read = (packet, index, nullBitmap) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBinaryTime();
break;

case FieldType.GEOMETRY:
this._read = (packet, index, nullBitmap) => {
let defaultVal = this.__getDefaultGeomVal();
return (packet, index, nullBitmap, opts) => {
if (isNullBitmap(index, nullBitmap)) {
if (this.dataTypeName) {
switch (this.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: this.dataTypeName };
}
}
return null;
return defaultVal;
}
return packet.readGeometry(this.dataTypeName);
return packet.readGeometry(defaultVal);
};
break;

case FieldType.JSON:
//for mysql only => parse string as JSON object
this._read = (packet, index, nullBitmap) =>
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : JSON.parse(packet.readStringLength());
break;

default:
if (this.dataTypeFormat && this.dataTypeFormat === 'json' && opts.autoJsonMap) {
this._read = (packet, index, nullBitmap) =>
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : JSON.parse(packet.readStringLength());
break;
}

if (this.collation.index === 63) {
this._read = (packet, index, nullBitmap) =>
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readBufferLengthEncoded();
break;
}

if (this.isSet()) {
this._read = (packet, index, nullBitmap) => {
return (packet, index, nullBitmap, opts) => {
if (isNullBitmap(index, nullBitmap)) return null;
const string = packet.readStringLength();
return string == null ? null : string === '' ? [] : string.split(',');
};
break;
}
this._read = (packet, index, nullBitmap) =>
return (packet, index, nullBitmap, opts) =>
isNullBitmap(index, nullBitmap) ? null : packet.readStringLength();
break;
}
} else {
switch (this.columnType) {
Expand All @@ -213,16 +181,14 @@ class ColumnDef {
case FieldType.INT:
case FieldType.INT24:
case FieldType.YEAR:
this._read = (packet) => packet.readIntLengthEncoded();
break;
return (packet, index, nullBitmap, opts) => packet.readIntLengthEncoded();

case FieldType.FLOAT:
case FieldType.DOUBLE:
this._read = (packet) => packet.readFloatLengthCoded();
break;
return (packet, index, nullBitmap, opts) => packet.readFloatLengthCoded();

case FieldType.BIGINT:
this._read = (packet, index, nullBitmap, opts) => {
return (packet, index, nullBitmap, opts) => {
const val = packet.readBigIntLengthEncoded();
if (val != null && (opts.bigIntAsNumber || opts.supportBigNumbers)) {
if (opts.supportBigNumbers && (opts.bigNumberStrings || !Number.isSafeInteger(Number(val)))) {
Expand All @@ -232,11 +198,10 @@ class ColumnDef {
}
return val;
};
break;

case FieldType.DECIMAL:
case FieldType.NEWDECIMAL:
this._read = (packet, index, nullBitmap, opts) => {
return (packet, index, nullBitmap, opts) => {
const valDec = packet.readDecimalLengthEncoded();
if (valDec != null && (opts.decimalAsNumber || opts.supportBigNumbers)) {
if (opts.supportBigNumbers && (opts.bigNumberStrings || !Number.isSafeInteger(Number(valDec)))) {
Expand All @@ -246,85 +211,98 @@ class ColumnDef {
}
return valDec;
};
break;

case FieldType.DATE:
this._read = (packet, index, nullBitmap, opts) => {
return (packet, index, nullBitmap, opts) => {
if (opts.dateStrings) {
return packet.readAsciiStringLengthEncoded();
}
return packet.readDate();
};
break;

case FieldType.DATETIME:
case FieldType.TIMESTAMP:
this._read = (packet, index, nullBitmap, opts) => {
return (packet, index, nullBitmap, opts) => {
if (opts.dateStrings) {
return packet.readAsciiStringLengthEncoded();
}
return packet.readDateTime(opts);
};
break;

case FieldType.TIME:
this._read = (packet) => packet.readAsciiStringLengthEncoded();
break;
return (packet, index, nullBitmap, opts) => packet.readAsciiStringLengthEncoded();

case FieldType.GEOMETRY:
this._read = (packet) => packet.readGeometry(this.dataTypeName);
break;
let defaultVal = this.__getDefaultGeomVal();
return (packet, index, nullBitmap, opts) => packet.readGeometry(defaultVal);

case FieldType.JSON:
//for mysql only => parse string as JSON object
this._read = (packet) => JSON.parse(packet.readStringLength());
break;
return (packet, index, nullBitmap, opts) => JSON.parse(packet.readStringLength());

default:
if (this.dataTypeFormat && this.dataTypeFormat === 'json' && opts.autoJsonMap) {
this._read = (packet) => JSON.parse(packet.readStringLength());
break;
return (packet, index, nullBitmap, opts) => JSON.parse(packet.readStringLength());
}

if (this.collation.index === 63) {
this._read = (packet) => packet.readBufferLengthEncoded();
break;
return (packet, index, nullBitmap, opts) => packet.readBufferLengthEncoded();
}

if (this.isSet()) {
this._read = (packet) => {
return (packet, index, nullBitmap, opts) => {
const string = packet.readStringLength();
return string == null ? null : string === '' ? [] : string.split(',');
};
break;
}
this._read = (packet) => packet.readStringLength();
return (packet, index, nullBitmap, opts) => packet.readStringLength();
}
}
}

__getDefaultGeomVal() {
if (this.dataTypeName) {
switch (this.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: this.dataTypeName };
}
}
return null;
}
db() {
return this._parse.packet.readString(this._parse.dbOffset, this._parse.dbLength);
return this._stringParser.packet.readString(this._stringParser.dbOffset, this._stringParser.dbLength);
}

schema() {
return this._parse.packet.readString(this._parse.dbOffset, this._parse.dbLength);
return this._stringParser.packet.readString(this._stringParser.dbOffset, this._stringParser.dbLength);
}

table() {
return this._parse.packet.readString(this._parse.tableOffset, this._parse.tableLength);
return this._stringParser.packet.readString(this._stringParser.tableOffset, this._stringParser.tableLength);
}

orgTable() {
return this._parse.packet.readString(this._parse.orgTableOffset, this._parse.orgTableLength);
return this._stringParser.packet.readString(this._stringParser.orgTableOffset, this._stringParser.orgTableLength);
}

name() {
return this._parse.packet.readString(this._parse.nameOffset, this._parse.nameLength);
return this._stringParser.packet.readString(this._stringParser.nameOffset, this._stringParser.nameLength);
}

orgName() {
return this._parse.packet.readString(this._parse.orgNameOffset, this._parse.orgNameLength);
return this._stringParser.packet.readString(this._stringParser.orgNameOffset, this._stringParser.orgNameLength);
}

signed() {
Expand Down
Loading

0 comments on commit 3f9b877

Please sign in to comment.