nxkit
Version:
This is a collection of tools, independent of any other libraries
286 lines (285 loc) • 9.09 kB
JavaScript
;
/* ***** 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 util_1 = require("../util");
const db_1 = require("../db");
const constants_1 = require("./constants");
const query_1 = require("./query");
const outgoing_packet_1 = require("./outgoing_packet");
const connection_1 = require("./connection");
const parser_1 = require("./parser");
const util_2 = require("../util");
class ErrorPacket extends parser_1.Packet {
constructor(err) {
super();
this.type = parser_1.Constants.ERROR_PACKET;
this.error = err;
}
toJSON() { return this.error; }
}
exports.ErrorPacket = ErrorPacket;
//public:
class Mysql extends db_1.Database {
/**
* constructor function
*/
constructor(options) {
super(options);
this._connection = null;
this._connecting = false;
this._transaction = false;
this._queue = [];
}
//close back connect
_close() {
var self = this;
var connection = self._connection;
self._connection = null;
if (connection) {
connection.onPacket.off('Mysql');
connection.onError.off('Mysql');
try {
connection.idle();
}
catch (err) {
console.error(err);
}
}
else if (self._connecting) {
self._connecting = false;
}
}
//net error and connection error
_handlError(err) {
var self = this;
self._close(); // close this connect
var item = self._queue[0];
var after = item ? item.after : null;
if (after) {
after(new ErrorPacket(err));
}
else {
self.onError.trigger(err);
self._dequeue();
console.error(err);
}
}
//onpacket handle
_handlePacket(packet) {
var self = this;
// @TODO Simplify the code below and above as well
var item = self._queue[0];
var after = item ? item.after : null;
if (after) {
after(packet);
}
else {
if (packet.type === parser_1.Constants.ERROR_PACKET) {
self.onError.trigger(packet.toJSON());
console.error(packet);
}
self._dequeue();
}
}
_after(cb) {
var self = this;
return function (packet) {
var data = packet.toJSON();
if (packet.type === parser_1.Constants.ERROR_PACKET) {
util_1.default.nextTick(cb, data);
}
else {
util_1.default.nextTick(cb, null, [data]);
}
self._dequeue();
};
}
//get connect
_connect() {
var self = this;
if (self._connecting)
return;
self._connecting = true;
util_2.default.assert(!self._connection, '_connection null ??');
connection_1.Connection.resolve(self.options, function (err, connection) {
var _a;
if (err) {
self._handlError(err);
}
else if (self._connecting && self._queue.length) {
if (!connection)
throw new Error('connection null ??');
connection.onPacket.on(e => self._handlePacket(e.data), 'Mysql');
connection.onError.on(e => self._handlError(e.data), 'Mysql');
self._connection = connection;
self._connecting = false;
self._exec();
}
else {
self._connecting = false;
(_a = connection) === null || _a === void 0 ? void 0 : _a.idle();
}
});
}
//write packet
_write(packet) {
this._connection.write(packet.buffer);
}
_exec() {
var self = this;
util_1.default.assert(this._connection, 'this._connection null ??');
util_1.default.assert(self._queue.length, 'self._queue.length == 0 ??');
try {
self._queue[0].exec();
}
catch (err) {
self._handlError(err);
}
}
//enqueue
_enqueue(exec, after) {
var self = this;
self._queue.push({ exec, after });
if (self._connection) {
if (self._queue.length === 1) {
if (self._connection) {
self._exec();
}
}
}
else {
self._connect();
}
}
//dequeue
_dequeue() {
var self = this;
self._queue.shift();
if (self._queue.length) {
if (self._connection) {
self._exec();
}
else {
self._connect();
}
}
}
/**
* is connection
*/
get connected() {
return !!this._connection;
}
statistics(cb) {
var self = this;
self._enqueue(function () {
var packet = new outgoing_packet_1.OutgoingPacket(1);
packet.writeNumber(1, constants_1.default.COM_STATISTICS);
self._write(packet);
}, self._after(cb));
}
query(sql, cb) {
var self = this;
var query = new query_1.Query(sql);
if (cb) {
var dataSet = [];
var rows = [];
var fields = {};
query.onResolve.on(function (e) {
rows = [];
fields = {};
dataSet.push(e.data ? e.data : { rows, fields });
});
query.onField.on(function (e) {
var field = e.data;
fields[field.name] = field;
});
query.onRow.on(function (e) {
rows.push(e.data);
});
query.onEnd.on(function () {
util_1.default.nextTick(cb, null, dataSet);
self._dequeue();
});
query.onError.on(function (e) {
util_1.default.nextTick(cb, e.data);
self._dequeue();
});
}
else {
query.onEnd.on(function () {
self._dequeue();
});
query.onError.on(function () {
self._dequeue();
});
}
self._enqueue(function () {
var packet = new outgoing_packet_1.OutgoingPacket(1 + Buffer.byteLength(sql, 'utf-8'));
packet.writeNumber(1, constants_1.default.COM_QUERY);
packet.write(sql, 'utf-8');
self._write(packet);
}, function (packet) {
query.handlePacket(packet);
});
return query;
}
close() {
var self = this;
if (self._queue.length) {
if (self._transaction)
self.commit();
self._enqueue(function () {
self._close();
self._dequeue();
});
}
else {
self._close();
}
}
transaction() {
if (this._transaction)
return;
this._transaction = true;
this.query('START TRANSACTION');
}
commit() {
this._transaction = false;
this.query('COMMIT');
}
rollback() {
this._queue = [];
this._transaction = false;
this.query('ROLLBACK');
}
}
exports.Mysql = Mysql;