UNPKG

nxkit

Version:

This is a collection of tools, independent of any other libraries

199 lines (198 loc) 9.48 kB
"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;