sybase-devdiniz
Version:
A simple node.js wrapper around a java/jconnect app that provides easy access to Sybase Databases without having to install odbc or freetds.
141 lines (116 loc) • 4.39 kB
JavaScript
// src/SybaseDB.js
var spawn = require('child_process').spawn;
var JSONStream = require('JSONStream');
var fs = require("fs");
var path = require("path");
function Sybase(host, port, dbname, username, password, logTiming, pathToJavaBridge, { encoding = "utf8", extraLogs = false, ...options } = {}) {
this.connected = false;
this.host = host;
this.port = port;
this.dbname = dbname;
this.username = username;
this.password = password;
this.logTiming = (logTiming === true);
this.encoding = encoding;
this.extraLogs = extraLogs;
this.options = options; // Propriedades adicionais para o Java
this.pathToJavaBridge = pathToJavaBridge;
if (this.pathToJavaBridge === undefined) {
this.pathToJavaBridge = path.resolve(__dirname, "..", "JavaSybaseLink", "dist", "JavaSybaseLink.jar");
}
this.queryCount = 0;
this.currentMessages = {}; // lookup msgId to message sent and callback details.
this.jsonParser = JSONStream.parse();
}
Sybase.prototype.log = function(msg) {
if (this.extraLogs) {
console.log(msg);
}
};
Sybase.prototype.connect = function(callback) {
var that = this;
var args = ["-jar", this.pathToJavaBridge, this.host, this.port, this.dbname, this.username, this.password];
// Adiciona propriedades adicionais no formato CHAVE=VALOR, se houver
if (this.options) {
for (var key in this.options) {
if (this.options.hasOwnProperty(key)) {
args.push(key + "=" + this.options[key]);
}
}
}
this.javaDB = spawn('java', args);
var hrstart = process.hrtime();
this.javaDB.stdout.once("data", function(data) {
if ((data + "").trim() != "connected") {
callback(new Error("Error connecting " + data));
return;
}
that.javaDB.stderr.removeAllListeners("data");
that.connected = true;
that.javaDB.stdout.setEncoding(that.encoding)
.pipe(that.jsonParser)
.on("data", function(jsonMsg) { that.onSQLResponse.call(that, jsonMsg); });
that.javaDB.stderr.on("data", function(err) { that.onSQLError.call(that, err); });
callback(null, data);
});
this.javaDB.stderr.once("data", function(data) {
that.javaDB.stdout.removeAllListeners("data");
that.javaDB.kill();
callback(new Error(data));
});
};
Sybase.prototype.disconnect = function() {
this.javaDB.kill();
this.connected = false;
};
Sybase.prototype.isConnected = function() {
return this.connected;
};
Sybase.prototype.query = function(sql, callback) {
if (!this.isConnected()) {
callback(new Error("database isn't connected."));
return;
}
var hrstart = process.hrtime();
this.queryCount++;
var msg = {
msgId: this.queryCount,
sql: sql,
sentTime: (new Date()).getTime(),
callback: callback,
hrstart: hrstart
};
this.currentMessages[msg.msgId] = msg;
var strMsg = JSON.stringify(msg).replace(/[\n]/g, '\\n');
this.javaDB.stdin.write(strMsg + "\n");
this.log("sql request written: " + strMsg);
};
Sybase.prototype.onSQLResponse = function(jsonMsg) {
var request = this.currentMessages[jsonMsg.msgId];
delete this.currentMessages[jsonMsg.msgId];
var result = jsonMsg.result;
if (result.length === 1)
result = result[0];
var currentTime = (new Date()).getTime();
var sendTimeMS = currentTime - jsonMsg.javaEndTime;
var hrend = process.hrtime(request.hrstart);
var javaDuration = (jsonMsg.javaEndTime - jsonMsg.javaStartTime);
var err = (jsonMsg.error !== undefined) ? new Error(jsonMsg.error) : null;
if (this.logTiming)
console.log("Execution time (hr): %ds %dms dbTime: %dms dbSendTime: %d sql=%s", hrend[0], hrend[1]/1000000, javaDuration, sendTimeMS, request.sql);
request.callback(err, result);
};
Sybase.prototype.onSQLError = function(data) {
var error = new Error(data);
var callBackFuncitons = [];
for (var k in this.currentMessages) {
if (this.currentMessages.hasOwnProperty(k)) {
callBackFuncitons.push(this.currentMessages[k].callback);
}
}
this.currentMessages = [];
callBackFuncitons.forEach(function(cb) {
cb(error);
});
};
module.exports = Sybase;