nxkit
Version:
This is a collection of tools, independent of any other libraries
199 lines (198 loc) • 9.48 kB
JavaScript
"use strict";
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2015, xuewen.chu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of xuewen.chu nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL xuewen.chu BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
Object.defineProperty(exports, "__esModule", { value: true });
const event_1 = require("../event");
const parser_1 = require("./parser");
var FieldType;
(function (FieldType) {
FieldType[FieldType["FIELD_TYPE_DECIMAL"] = 0] = "FIELD_TYPE_DECIMAL";
FieldType[FieldType["FIELD_TYPE_TINY"] = 1] = "FIELD_TYPE_TINY";
FieldType[FieldType["FIELD_TYPE_SHORT"] = 2] = "FIELD_TYPE_SHORT";
FieldType[FieldType["FIELD_TYPE_LONG"] = 3] = "FIELD_TYPE_LONG";
FieldType[FieldType["FIELD_TYPE_FLOAT"] = 4] = "FIELD_TYPE_FLOAT";
FieldType[FieldType["FIELD_TYPE_DOUBLE"] = 5] = "FIELD_TYPE_DOUBLE";
FieldType[FieldType["FIELD_TYPE_NULL"] = 6] = "FIELD_TYPE_NULL";
FieldType[FieldType["FIELD_TYPE_TIMESTAMP"] = 7] = "FIELD_TYPE_TIMESTAMP";
FieldType[FieldType["FIELD_TYPE_LONGLONG"] = 8] = "FIELD_TYPE_LONGLONG";
FieldType[FieldType["FIELD_TYPE_INT24"] = 9] = "FIELD_TYPE_INT24";
FieldType[FieldType["FIELD_TYPE_DATE"] = 10] = "FIELD_TYPE_DATE";
FieldType[FieldType["FIELD_TYPE_TIME"] = 11] = "FIELD_TYPE_TIME";
FieldType[FieldType["FIELD_TYPE_DATETIME"] = 12] = "FIELD_TYPE_DATETIME";
FieldType[FieldType["FIELD_TYPE_YEAR"] = 13] = "FIELD_TYPE_YEAR";
FieldType[FieldType["FIELD_TYPE_NEWDATE"] = 14] = "FIELD_TYPE_NEWDATE";
FieldType[FieldType["FIELD_TYPE_VARCHAR"] = 15] = "FIELD_TYPE_VARCHAR";
FieldType[FieldType["FIELD_TYPE_BIT"] = 16] = "FIELD_TYPE_BIT";
FieldType[FieldType["FIELD_TYPE_NEWDECIMAL"] = 246] = "FIELD_TYPE_NEWDECIMAL";
FieldType[FieldType["FIELD_TYPE_ENUM"] = 247] = "FIELD_TYPE_ENUM";
FieldType[FieldType["FIELD_TYPE_SET"] = 248] = "FIELD_TYPE_SET";
FieldType[FieldType["FIELD_TYPE_TINY_BLOB"] = 249] = "FIELD_TYPE_TINY_BLOB";
FieldType[FieldType["FIELD_TYPE_MEDIUM_BLOB"] = 250] = "FIELD_TYPE_MEDIUM_BLOB";
FieldType[FieldType["FIELD_TYPE_LONG_BLOB"] = 251] = "FIELD_TYPE_LONG_BLOB";
FieldType[FieldType["FIELD_TYPE_BLOB"] = 252] = "FIELD_TYPE_BLOB";
FieldType[FieldType["FIELD_TYPE_VAR_STRING"] = 253] = "FIELD_TYPE_VAR_STRING";
FieldType[FieldType["FIELD_TYPE_STRING"] = 254] = "FIELD_TYPE_STRING";
FieldType[FieldType["FIELD_TYPE_GEOMETRY"] = 255] = "FIELD_TYPE_GEOMETRY";
})(FieldType = exports.FieldType || (exports.FieldType = {}));
;
class Field {
constructor(name, type) {
this.name = name;
this.type = type;
}
}
exports.Field = Field;
class Query {
constructor(sql) {
this._eofs = 0;
this._fields = null;
this._rowIndex = 0;
this.onError = new event_1.EventNoticer('Error', this);
this.onResolve = new event_1.EventNoticer('Resolve', this);
this.onField = new event_1.EventNoticer('Field', this);
this.onRow = new event_1.EventNoticer('Row', this);
this.onEnd = new event_1.EventNoticer('End', this);
this.sql = sql;
}
handlePacket(packet) {
// We can't do this require() on top of the file.
// That's because there is circular dependency and we're overwriting
var self = this;
switch (packet.type) {
case parser_1.Constants.OK_PACKET:
this.onResolve.trigger(packet.toJSON());
if (packet.data.serverStatus == 2 || packet.data.serverStatus == 3) {
this.onEnd.trigger();
}
break;
case parser_1.Constants.ERROR_PACKET:
packet.data.sql = self.sql;
this.onError.trigger(packet.toJSON());
break;
case parser_1.Constants.FIELD_PACKET:
if (!this._fields) {
this._fields = [];
this.onResolve.trigger(null);
}
var field = new Field(packet.data.name || '', packet.data.fieldType || -1);
this._fields.push(field);
this.onField.trigger(field);
break;
case parser_1.Constants.EOF_PACKET:
if (!this._eofs) {
this._eofs = 1;
}
else {
this._eofs++;
}
if (this._eofs == 2) {
this._fields = null;
this._eofs = 0;
if (packet.data.serverStatus == 34 || packet.data.serverStatus == 2) {
this.onEnd.trigger();
}
}
break;
case parser_1.Constants.ROW_DATA_PACKET: {
let row = {};
let field = null;
let value = null;
let fields = this._fields;
this._rowIndex = 0;
this._row = row;
packet.onData.on(function (e) {
var data = e.data;
var buffer = data.buffer;
var remaining = data.remaining;
if (!field)
field = fields[self._rowIndex];
if (buffer) {
if (value) {
value = Buffer.concat([value, buffer]);
}
else {
value = buffer;
}
}
else {
row[field.name] = value = null;
}
if (remaining !== 0) {
return;
}
self._rowIndex++;
// NOTE: need to handle more data types, such as binary data
if (value !== null) {
var str_value = value.toString('utf8');
switch (field.type) {
case FieldType.FIELD_TYPE_TIMESTAMP:
case FieldType.FIELD_TYPE_DATE:
case FieldType.FIELD_TYPE_DATETIME:
case FieldType.FIELD_TYPE_NEWDATE:
row[field.name] = new Date(str_value);
break;
case FieldType.FIELD_TYPE_TINY:
case FieldType.FIELD_TYPE_SHORT:
case FieldType.FIELD_TYPE_LONG:
case FieldType.FIELD_TYPE_LONGLONG:
case FieldType.FIELD_TYPE_INT24:
case FieldType.FIELD_TYPE_YEAR:
row[field.name] = parseInt(str_value, 10);
break;
case FieldType.FIELD_TYPE_FLOAT:
case FieldType.FIELD_TYPE_DOUBLE:
// decimal types cannot be parsed as floats because
// V8 Numbers have less precision than some MySQL Decimals
row[field.name] = parseFloat(str_value);
break;
case FieldType.FIELD_TYPE_BIT:
row[field.name] = str_value == '\u0000' ? false : true;
break;
default:
row[field.name] = str_value;
break;
}
}
if (self._rowIndex == fields.length) {
delete self._row;
delete self._rowIndex;
self.onRow.trigger(row);
return;
}
field = null;
value = null;
});
break;
}
default: break;
}
}
}
exports.Query = Query;