Socket
Socket
Sign inDemoInstall

hdb

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hdb - npm Package Compare versions

Comparing version 0.2.0 to 0.3.1

lib/protocol/auth/Manager.js

6

index.js

@@ -18,6 +18,4 @@ // Copyright 2013 SAP AG.

exports.Client = lib.Client;
exports.createClient = lib.createClient;
exports.Stringifier = lib.Stringifier;
exports.createJSONStringifier = lib.createJSONStringifier;
exports.createClient = function createClient(options) {
return new lib.Client(options);
};
exports.createJSONStringifier = lib.createJSONStringifier;

@@ -30,22 +30,10 @@ // Copyright 2013 SAP AG.

var settings = this._settings = util.extend({
this._settings = util.extend({
fetchSize: 1024,
holdCursorsOverCommit: true,
scrollableCursor: true
scrollableCursor: true,
autoReconnect: false
}, options);
this._connection = new Connection(settings);
this.setAutoCommit(true);
var self = this;
function onerror(err) {
self.emit('error', err);
}
this._connection.on('error', onerror);
function onclose(hadError) {
self._connection.removeListener('error', onerror);
self.emit('close', hadError);
}
this._connection.once('close', onclose);
this._connection = this._createConnection(this._settings);
this._addListeners(this._connection);
}

@@ -106,3 +94,3 @@

Client.prototype.get = function (key) {
if (key === undefined) {
if (util.isUndefined(key)) {
return this._settings;

@@ -114,3 +102,3 @@ }

Client.prototype.set = function (key, value) {
if (!value && typeof util.isObject(key)) {
if (!value && util.isObject(key)) {
this._settings = util.extend(this._settings, key);

@@ -129,12 +117,30 @@ } else {

var settings = this._settings;
function addOption(name) {
/* jshint validthis:true */
if (name in settings) {
this[name] = settings[name];
}
}
var openOptions = {
host: this._settings.host,
port: this._settings.port
host: settings.host,
port: settings.port
};
['pfx', 'key', 'cert', 'ca', 'passphrase', 'rejectUnauthorized',
'secureProtocol'
].forEach(addOption, openOptions);
util.extend(openOptions, options);
var authOptions = util.extend({
user: this._settings.user,
password: this._settings.password
}, options);
var connectOptions = {};
['user', 'password', 'assertion', 'sessionCookie'].forEach(addOption,
connectOptions);
util.extend(connectOptions, options);
// SAML assertion can only be used once
if (this._settings.assertion) {
this._settings.assertion = undefined;
}
var self = this;

@@ -151,10 +157,26 @@

function authenticate() {
self._connection.connect(authOptions, done);
function onopen(err) {
if (err) {
return done(err);
}
self._connection.connect(connectOptions, done);
}
if (this._connection.readyState === 'new') {
this._connection.open(openOptions, authenticate);
this._connection.open(openOptions, onopen);
} else if (this._connection.readyState === 'closed') {
this._connection = this._createConnection(this._settings);
this._addListeners(this._connection);
this._connection.open(openOptions, onopen);
} else if (this._connection.readyState === 'disconnected') {
this._connection.connect(connectOptions, done);
} else {
authenticate();
if (util.isFunction(cb)) {
util.setImmediate(function deferError() {
var msg = util.format('Cannot connect in state "%s"', self.readyState);
var err = new Error(msg);
err.code = 'EHDBCONNECT';
cb(err);
});
}
}

@@ -179,5 +201,6 @@ return this;

Client.prototype.end = function end() {
Client.prototype.close = function close() {
this._connection.close();
};
Client.prototype.end = Client.prototype.close;

@@ -195,5 +218,3 @@ Client.prototype.prepare = function prepare(command, cb) {

var statement = new Statement(this._connection);
this._connection.prepare({
command: command
}, function onreply(err, reply) {
this._connection.prepare(options, function onreply(err, reply) {
statement.handle(err, reply, cb);

@@ -204,2 +225,6 @@ });

Client.prototype.destroy = function destroy(err) {
this._connection.destroy(err);
};
Client.prototype.exec = function exec(command, options, cb) {

@@ -221,2 +246,33 @@ var defaults = {

Client.prototype._createConnection = function _createConnection(settings) {
return new Connection(settings);
};
Client.prototype._addListeners = function _addListeners(connection) {
var self = this;
function cleanup() {
connection.removeListener('error', onerror);
connection.removeListener('close', onclose);
}
function onerror(err) {
self.emit('error', err);
}
connection.on('error', onerror);
function onclose(hadError) {
cleanup();
self.emit('close', hadError);
if (hadError && self.get('autoReconnect')) {
self.connect();
}
}
connection.on('close', onclose);
};
Client.prototype._createResult = function _createResult(connection, options) {
return new Result(connection, options);
};
function executeDirect(defaults, command, options, cb) {

@@ -237,3 +293,3 @@ /* jshint validthis: true */

};
var result = new Result(this._connection, options);
var result = this._createResult(this._connection, options);

@@ -240,0 +296,0 @@ function onreply(err, reply) {

@@ -17,6 +17,22 @@ // Copyright 2013 SAP AG.

var util = exports.util = require('./util');
util.extend(exports, require('./protocol'));
exports.Client = require('./Client');
exports.createJSONStringifier = function createJSONStringifier() {
return new exports.Stringifier({
var Client = exports.Client = require('./Client');
var protocol = require('./protocol');
util.extend(exports, protocol);
exports.createJSONStringifier = createJSONStringifier;
exports.createClient = createClient;
exports.connect = connect;
function connect(options, cb) {
var client = createClient(options);
client.connect(cb);
return client;
}
function createClient(options) {
return new Client(options);
}
function createJSONStringifier() {
return new protocol.Stringifier({
header: '[',

@@ -27,2 +43,2 @@ footer: ']',

});
};
}

@@ -16,2 +16,6 @@ // Copyright 2013 SAP AG.

exports.SCRAMSHA256 = require('./scramsha256');
var Manager = require('./Manager');
exports.createManager = function createManager(options) {
return new Manager(options);
};

@@ -17,2 +17,3 @@ // Copyright 2013 SAP AG.

var net = require('net');
var tls = require('tls');
var os = require('os');

@@ -47,2 +48,3 @@ var EventEmitter = require('events').EventEmitter;

var self = this;
// public

@@ -59,9 +61,5 @@ this.clientId = [process.pid || 'nodejs', os.hostname()].join('@');

this._transaction = new Transaction();
var self = this;
function onerror(err) {
this._transaction.once('error', function onerror(err) {
self.destroy(err);
}
this._transaction.once('error', onerror);
});
}

@@ -131,48 +129,49 @@

if (this._socket) {
return cb(new Error('Call open only once'));
util.setImmediate(function deferError() {
cb(new Error('Call open only once'));
});
return;
}
function done(err) {
function done(err, protocolVersion) {
if (err) {
self.emit('error', err);
} else {
self.emit('open');
return cb(err);
}
if (util.isFunction(cb)) {
cb(err);
}
}
function onready(err, protocolVersion) {
if (err) {
return done(err);
}
self._protocolVersion = protocolVersion;
self._initConnection();
done(null);
self._addListeners(self._socket);
self.emit('open');
cb();
}
this._socket = this._createSocket(options);
this._initSocket(this._socket, onready);
this._socket = this._connect(options, done);
};
Connection.prototype._createSocket = function _createSocket(options) {
var socket = net.connect(util.extend(options, {
allowHalfOpen: false
}));
Connection.prototype._connect = function _connect(options, cb) {
var tcp;
if ('key' in options || 'cert' in options || 'ca' in options ||
'pfx' in options) {
tcp = tls;
} else {
tcp = net;
}
options.allowHalfOpen = false;
var socket = tcp.connect(options);
socket.setNoDelay(true);
return socket;
};
Connection.prototype._initSocket = function _initSocket(socket, cb) {
function cleanup() {
socket.removeListener('connect', onconnect);
socket.removeListener('error', onerror);
socket.removeListener('data', ondata);
socket.removeListener('connect', onconnect);
}
function onconnect() {
function onconnect(err) {
socket.write(initializationRequestBuffer);
}
socket.on('connect', onconnect);
socket.once('connect', onconnect);
function onerror(err) {
cleanup();
cb(err);
}
socket.on('error', onerror);
function ondata(chunk) {

@@ -187,15 +186,17 @@ cleanup();

}
socket.once('data', ondata);
socket.on('data', ondata);
function onerror(err) {
cleanup();
cb(err);
}
socket.on('error', onerror);
return socket;
};
Connection.prototype._initConnection = function _initConnection() {
Connection.prototype._addListeners = function _addListeners(socket) {
var self = this;
var packet = new MessageBuffer();
function cleanup() {
socket.removeListener('error', onerror);
socket.removeListener('data', ondata);
socket.removeListener('close', onclose);
}
// register listerners on socket

@@ -217,3 +218,3 @@ function ondata(chunk) {

}
this._socket.on('data', ondata);
socket.on('data', ondata);

@@ -223,15 +224,19 @@ function onerror(err) {

}
this._socket.on('error', onerror);
socket.on('error', onerror);
function onclose(hadError) {
self._socket.removeAllListeners();
self._socket = undefined;
self._state = undefined;
self._queue.abort();
self._queue = undefined;
cleanup();
self._cleanup();
self.emit('close', hadError);
}
this._socket.once('close', onclose);
socket.on('close', onclose);
};
Connection.prototype._cleanup = function _cleanup() {
this._socket = undefined;
this._state = undefined;
this._queue.abort();
this._queue = undefined;
};
Connection.prototype.send = function send(message, receive) {

@@ -243,3 +248,3 @@ if (this._statementContext) {

debug('send', message);
trace(SegmentKind.REQUEST, message);
trace('REQUEST', message);

@@ -296,3 +301,3 @@ var size = MAX_PACKET_SIZE - PACKET_HEADER_LENGTH;

segment = ReplySegment.create(buffer, 0);
trace(segment.kind, segment);
trace(segment.kind === SegmentKind.ERROR ? 'ERROR' : 'REPLY', segment);
reply = segment.getReply();

@@ -342,27 +347,12 @@ this.setStatementContext(reply.statementContext);

var name = options.algorithm || 'SCRAMSHA256';
var authMethod = auth[name];
var algorithm = new authMethod.Algorithm(options.clientChallenge);
var manager;
try {
manager = auth.createManager(options);
} catch (err) {
return util.setImmediate(function deferError() {
cb(err);
});
}
var authOptions = {
authentication: {
user: options.user,
algorithm: name,
clientChallenge: algorithm.clientChallenge
}
};
var authMessage = request.authenticate(authMethod, authOptions);
var connOptions = {
authentication: {
user: options.user,
algorithm: name,
clientProof: undefined
},
clientId: this.clientId,
connectOptions: this.connectOptions.getOptions()
};
function connReceive(err, reply) {
/* jshint validthis:true */
if (err) {

@@ -374,2 +364,7 @@ return cb(err);

}
manager.finalize(reply.authentication);
self._settings.user = manager.userFromServer;
if (manager.sessionCookie) {
self._settings.sessionCookie = manager.sessionCookie;
}
self._queue.resume();

@@ -380,14 +375,19 @@ cb(null, reply);

function authReceive(err, reply) {
/* jshint validthis:true */
if (err) {
return cb(err);
}
var authReply = authMethod.Authentication.convert(reply.authentication);
algorithm.salts = [authReply.salt];
algorithm.serverChallenge = authReply.serverChallenge;
connOptions.authentication.clientProof = algorithm.getClientProof(options.password);
var connMessage = request.connect(authMethod, connOptions);
self.send(connMessage, connReceive);
try {
manager.initialize(reply.authentication);
} catch (err) {
return cb(err);
}
self.send(request.connect({
authentication: manager.finalData(),
clientId: self.clientId,
connectOptions: self.connectOptions.getOptions()
}), connReceive);
}
this.send(authMessage, authReceive);
this.send(request.authenticate({
authentication: manager.initialData()
}), authReceive);
};

@@ -402,3 +402,3 @@

}
self._statementContext = new part.StatementContext();
self._statementContext = undefined;
self._state = new ConnectionState();

@@ -567,8 +567,7 @@ cb(null, reply);

Connection.prototype.close = function close() {
var socket = this._socket;
var self = this;
function closeConnection() {
debug('close');
socket.readable = false;
socket.end();
self.destroy();
}

@@ -582,8 +581,5 @@ if (this._queue.empty && !this._queue.busy) {

Connection.prototype.destroy = function destroy(err) {
var socket = this._socket;
function destroySocket() {
socket.destroy(err);
if (this._socket) {
this._socket.destroy(err);
}
process.nextTick(destroySocket);
};

@@ -590,0 +586,0 @@

@@ -34,3 +34,3 @@ // Copyright 2013 SAP AG.

offset += 1;
if (fieldLength === 0xff) {
if (fieldLength > 245) {
fieldLength = buffer.readUInt16LE(offset);

@@ -69,7 +69,7 @@ offset += 2;

fieldLength = data.length;
if (fieldLength <= 250) {
if (fieldLength <= 245) {
buffer[offset] = fieldLength;
offset += 1;
} else {
buffer[offset] = 0xff;
buffer[offset] = 0xf6;
offset += 1;

@@ -92,3 +92,3 @@ buffer.writeUInt16LE(fieldLength, offset);

fieldLength = getByteLengthOfField(fields[i]);
if (fieldLength <= 250) {
if (fieldLength <= 245) {
byteLength += fieldLength + 1;

@@ -95,0 +95,0 @@ } else {

@@ -22,2 +22,3 @@ // Copyright 2013 SAP AG.

exports.Stringifier = require('./Stringifier');
exports.Transaction = require('./Transaction');
exports.Reader = require('./Reader');

@@ -24,0 +25,0 @@ exports.Writer = require('./Writer');

@@ -71,7 +71,7 @@ // Copyright 2013 SAP AG.

Reader.prototype.readString = function readString() {
this.readBytes('utf-8');
return this.readBytes('utf-8');
};
Reader.prototype.readBinary = function readBinary() {
this.readBytes();
return this.readBytes();
};

@@ -106,19 +106,21 @@

/* jshint bitwise:false */
if (!(this.buffer[this.offset + 1] & 0x80)) {
var high = this.buffer[this.offset + 1];
// msb not set ==> null
if (!(high & 0x80)) {
this.offset += 4;
return null;
}
var year = this.buffer.readInt16LE(this.offset, true);
if (year & 0x8000) {
year = year & 0x7fff;
}
if (year & 0x4000) {
year = year | 0x8000;
}
var month = this.buffer.readInt8(this.offset + 2, true) + 1;
var day = this.buffer.readInt8(this.offset + 3, true);
this.offset += 4;
return bignum.lpad4(year) + '-' +
bignum.lpad2(month) + '-' +
bignum.lpad2(day);
var year = this.buffer[this.offset];
this.offset += 2;
var month = this.buffer[this.offset] + 1;
this.offset += 1;
var day = this.buffer[this.offset];
this.offset += 1;
// msb set ==> not null
// unset msb and second most sb
high &= 0x3f;
year |= high << 8;
return util.lpad4(year) + '-' +
util.lpad2(month) + '-' +
util.lpad2(day);
};

@@ -128,16 +130,18 @@

/* jshint bitwise:false */
if (!(this.buffer[this.offset] & 0x80)) {
var hour = this.buffer[this.offset];
// msb not set ==> null
if (!(hour & 0x80)) {
this.offset += 4;
return null;
}
var hour = this.buffer.readInt8(this.offset, true);
if (hour & 0x80) {
hour = hour & 0x7f;
}
var min = this.buffer.readInt8(this.offset + 1, true);
var msec = this.buffer.readUInt16LE(this.offset + 2, true);
this.offset += 4;
return bignum.lpad2(hour) + ':' +
bignum.lpad2(min) + ':' +
bignum.lpad2(msec / 1000);
var min = this.buffer[this.offset + 1];
this.offset += 2;
var msec = this.buffer.readUInt16LE(this.offset, true);
this.offset += 2;
// msb set ==> not null
// unset msb
hour &= 0x7f;
return util.lpad2(hour) + ':' +
util.lpad2(min) + ':' +
util.lpad2(msec / 1000);
};

@@ -148,11 +152,12 @@

var time = this.readTime();
if (!date && !time) {
return null;
} else if (date && time) {
return date + 'T' + time;
} else if (date) {
return date;
} else {
return time;
if (date) {
if (time) {
return date + 'T' + time;
}
return date + 'T00:00:00';
}
if (time) {
return '0001-01-01T' + time;
}
return null;
};

@@ -181,3 +186,3 @@

this.offset += 8;
if (value === 315538070401) {
if (value === 315538070401 || value === 0) {
return null;

@@ -191,3 +196,3 @@ }

this.offset += 8;
if (value === '3155380704000000001') {
if (value === '3155380704000000001' || value === 0) {
return null;

@@ -197,3 +202,3 @@ }

var index = value.length - 7;
return value.substring(0, index) + bignum.lpad7(value.substring(index) -
return value.substring(0, index) + util.lpad7(value.substring(index) -
1);

@@ -200,0 +205,0 @@ } else {

@@ -87,19 +87,13 @@ // Copyright 2013 SAP AG.

function authenticate(method, options) {
function authenticate(options) {
var segment = createSegment(MessageType.AUTHENTICATE, options);
// authentication
segment.add({
kind: PartKind.AUTHENTICATION,
module: method.Authentication
}, options.authentication);
segment.add(PartKind.AUTHENTICATION, options.authentication);
return segment;
}
function connect(method, options) {
function connect(options) {
var segment = createSegment(MessageType.CONNECT, options);
// authentication
segment.add({
kind: PartKind.AUTHENTICATION,
module: method.Connect
}, options.authentication);
segment.add(PartKind.AUTHENTICATION, options.authentication);
// clientId

@@ -106,0 +100,0 @@ segment.add(PartKind.CLIENT_ID, options.clientId);

@@ -22,3 +22,2 @@ // Copyright 2013 SAP AG.

var TypeCode = common.TypeCode;
var FunctionCode = common.FunctionCode;

@@ -31,3 +30,3 @@

this._connection = connection;
this._resultSetMode = options.resultSetMode || options.autoFetch === false;
this._autoFetch = !! options.autoFetch;
this._readSize = options.readSize || Lob.DEFAULT_READ_SIZE;

@@ -99,3 +98,3 @@ this._resultSetMetadata = undefined;

if (this._resultSetMode) {
if (!this._autoFetch) {
return done(null, resultSets);

@@ -118,3 +117,3 @@ }

if (this._resultSetMode) {
if (!this._autoFetch) {
return done(null, resultSets);

@@ -121,0 +120,0 @@ }

@@ -257,5 +257,2 @@ // Copyright 2013 SAP AG.

}
if (!reply.resultSets.length) {
console.log(err, reply);
}
var data = reply.resultSets[0].data;

@@ -262,0 +259,0 @@ if (this._running) {

@@ -43,6 +43,4 @@ // Copyright 2013 SAP AG.

this.push(this.transformRows(thing));
} else if (util.isObject(thing)) {
} else {
this.push(this.transformRow(thing));
} else {
this.push('');
}

@@ -49,0 +47,0 @@ done();

@@ -62,7 +62,4 @@ // Copyright 2013 SAP AG.

this.error.fatal = true;
var self = this;
process.nextTick(function emitError() {
self.emit('error', self.error);
});
this.emit('error', this.error);
}
};

@@ -17,33 +17,6 @@ // Copyright 2013 SAP AG.

var INT_10_1 = Math.pow(10, 1);
var INT_10_2 = Math.pow(10, 2);
var zeropad = require('./zeropad');
var INT_10_3 = Math.pow(10, 3);
var INT_10_4 = Math.pow(10, 4);
var INT_10_5 = Math.pow(10, 5);
var INT_10_6 = Math.pow(10, 6);
var INT_10_7 = Math.pow(10, 7);
var INT_10_8 = Math.pow(10, 8);
var INT_10_9 = Math.pow(10, 9);
var INT_10_10 = Math.pow(10, 10);
var INT_10_11 = Math.pow(10, 11);
var INT_10_12 = Math.pow(10, 12);
var INT_10_13 = Math.pow(10, 13);
var BASE = Math.pow(10, 7);
var ZERO_1 = '0';
var ZERO_2 = '00';
var ZERO_3 = '000';
var ZERO_4 = '0000';
var ZERO_5 = '00000';
var ZERO_6 = '000000';
var ZERO_7 = '0000000';
var ZERO_8 = '00000000';
var ZERO_9 = '000000000';
var ZERO_10 = '0000000000';
var ZERO_11 = '00000000000';
var ZERO_12 = '000000000000';
var ZERO_13 = '0000000000000';
var BASE = INT_10_7;
var EXP_BIAS = 6176;

@@ -103,52 +76,2 @@

/* Decimal zero padding */
var MAX_DECIMAL_LENGTH = 35;
var ZEROS = [''];
for (var i = 1; i < MAX_DECIMAL_LENGTH; i++) {
ZEROS.push(ZEROS[i - 1] + '0');
}
function lpad14(number) {
/* jshint curly: false */
if (number >= INT_10_13) return number;
if (number >= INT_10_12) return ZERO_1 + number;
if (number >= INT_10_11) return ZERO_2 + number;
if (number >= INT_10_10) return ZERO_3 + number;
if (number >= INT_10_9) return ZERO_4 + number;
if (number >= INT_10_8) return ZERO_5 + number;
if (number >= INT_10_7) return ZERO_6 + number;
if (number >= INT_10_6) return ZERO_7 + number;
if (number >= INT_10_5) return ZERO_8 + number;
if (number >= INT_10_4) return ZERO_9 + number;
if (number >= INT_10_3) return ZERO_10 + number;
if (number >= INT_10_2) return ZERO_11 + number;
if (number >= INT_10_1) return ZERO_12 + number;
return ZERO_13 + number;
}
function lpad7(number) {
/* jshint curly: false */
if (number >= INT_10_6) return number;
if (number >= INT_10_5) return ZERO_1 + number;
if (number >= INT_10_4) return ZERO_2 + number;
if (number >= INT_10_3) return ZERO_3 + number;
if (number >= INT_10_2) return ZERO_4 + number;
if (number >= INT_10_1) return ZERO_5 + number;
return ZERO_6 + number;
}
function lpad4(number) {
/* jshint curly: false */
if (number >= INT_10_3) return number;
if (number >= INT_10_2) return ZERO_1 + number;
if (number >= INT_10_1) return ZERO_2 + number;
return ZERO_3 + number;
}
function lpad2(number) {
/* jshint curly: false */
if (number >= INT_10_1) return number;
return ZERO_1 + number;
}
function _readInt64(buffer, offset, unsigned) {

@@ -218,5 +141,5 @@

if (s === 1) {
return '' + x2 + lpad14(x1 * BASE + x0);
return '' + x2 + zeropad.lpad14(x1 * BASE + x0);
}
return '-' + x2 + lpad14(x1 * BASE + x0);
return '-' + x2 + zeropad.lpad14(x1 * BASE + x0);

@@ -386,7 +309,8 @@ }

if (x4) {
dec.m = '' + x4 + lpad14(x3 * BASE + x2) + lpad14(x1 * BASE + x0);
dec.m = '' + x4 + zeropad.lpad14(x3 * BASE + x2) + zeropad.lpad14(x1 * BASE +
x0);
return dec;
}
if (x3) {
dec.m = '' + (x3 * BASE + x2) + lpad14(x1 * BASE + x0);
dec.m = '' + (x3 * BASE + x2) + zeropad.lpad14(x1 * BASE + x0);
return dec;

@@ -400,3 +324,3 @@ }

}
dec.m = '' + x2 + lpad14(x1 * BASE + x0);
dec.m = '' + x2 + zeropad.lpad14(x1 * BASE + x0);
return dec;

@@ -452,3 +376,3 @@ }

i = '0';
f = zeros(-k) + d;
f = zeropad.ZEROS[-k] + d;
} else {

@@ -459,3 +383,3 @@ i = '0';

} else if (e > 0) {
i = d + zeros(e);
i = d + zeropad.ZEROS[e];
f = '';

@@ -476,3 +400,3 @@ } else {

} else if (l < frac) {
f += zeros(frac - l);
f += zeropad.ZEROS[frac - l];
}

@@ -482,12 +406,2 @@ return i + '.' + f;

function zeros(l) {
if (l < MAX_DECIMAL_LENGTH) {
return ZEROS[l];
}
var z = '';
for (var i = 0; i < l; i++) {
z += '0';
}
return z;
}

@@ -705,6 +619,7 @@ function _writeInt64(buffer, value, offset, unsigned) {

if (x4) {
return '' + x4 + lpad14(x3 * BASE + x2) + lpad14(x1 * BASE + x0);
return '' + x4 + zeropad.lpad14(x3 * BASE + x2) + zeropad.lpad14(x1 * BASE +
x0);
}
if (x3) {
return '' + (x3 * BASE + x2) + lpad14(x1 * BASE + x0);
return '' + (x3 * BASE + x2) + zeropad.lpad14(x1 * BASE + x0);
}

@@ -716,3 +631,3 @@ if (x2) {

}
return '' + x2 + lpad14(x1 * BASE + x0);
return '' + x2 + zeropad.lpad14(x1 * BASE + x0);

@@ -906,6 +821,2 @@ }

exports.readDecFloat = readDecFloat;
exports.readDecFixed = readDecFixed;
exports.lpad2 = lpad2;
exports.lpad4 = lpad4;
exports.lpad7 = lpad7;
exports.lpad14 = lpad14;
exports.readDecFixed = readDecFixed;

@@ -61,2 +61,7 @@ // Copyright 2013 SAP AG.

exports.bignum = require('./bignum');
exports.calendar = require('./calendar');
exports.Queue = require('./Queue');
extend(exports, require('./zeropad'));
var debuglog;

@@ -78,3 +83,2 @@ if (util.debuglog) {

var traceFunction;
exports.tracelog = function tracelog() {

@@ -84,8 +88,10 @@ if (typeof traceFunction !== 'function') {

var timestamp = Math.floor(Date.now() / 1000);
var filename = path.join(os.tmpDir(), 'hdb.trace.' + timestamp);
var filename = path.join(os.tmpDir(), 'hdb.trace.' + timestamp + '.log');
console.log('Trace to file', filename);
traceFunction = function trace(kind, segment) {
fs.appendFileSync(filename, util.inspect(segment, {
depth: 9
}));
fs.appendFileSync(filename,
kind + '\n' +
util.inspect(segment, {
depth: 9
}));
};

@@ -99,6 +105,2 @@ } else {

exports.bignum = require('./bignum');
exports.Queue = require('./Queue');
function extend(obj) {

@@ -105,0 +107,0 @@ function extendOnce(source) {

@@ -8,3 +8,3 @@ {

"description": "SAP HANA Database Client for Node",
"version": "0.2.0",
"version": "0.3.1",
"repository": {

@@ -33,12 +33,12 @@ "type": "git",

"devDependencies": {
"should": "~2.1.0",
"mocha": "~1.14.0",
"async": "~0.2.9",
"debuglog": "~0.0.2",
"readable-stream": "~1.1.9",
"should": "~3.1.3",
"mocha": "~1.17.1",
"async": "~0.2.10",
"debuglog": "~1.0.0",
"readable-stream": "~1.1.11",
"generic-pool": "~2.0.4",
"fstream": "~0.1.24",
"concat-stream": "~1.2.0"
"fstream": "~0.1.25",
"concat-stream": "~1.4.1"
},
"optionalDependencies": {}
}

@@ -7,4 +7,19 @@ SAP HANA Database Client for Node

[![Build Status](https://secure.travis-ci.org/SAP/node-hdb.png)](http://travis-ci.org/SAP/node-hdb)
[![NPM](https://nodei.co/npm/hdb.png?compact=true)](https://npmjs.org/package/hdb) &nbsp;&nbsp;&nbsp; [![Build Status](https://secure.travis-ci.org/SAP/node-hdb.png)](http://travis-ci.org/SAP/node-hdb)
Table of contents
-------------
* [Install](#install)
* [Getting started](#getting-started)
* [Establish a database connection](#establish-a-database-connection)
* [Direct Statement Execution](#direct-statement-execution)
* [Prepared Statement Execution](#prepared-statement-execution)
* [Streaming results](#streaming-results)
* [Transaction handling](#transaction-handling)
* [Streaming Large Objects](#streaming-large-objects)
* [Running tests](#running-tests)
* [Running examples](#running-examples)
* [Todo](#todo)
Install

@@ -15,3 +30,5 @@ -------

[![NPM](https://nodei.co/npm/hdb.png?compact=true)](https://npmjs.org/package/hdb)
```bash
npm install hdb
```

@@ -26,7 +43,9 @@ or clone from the [GitHub repository](https://github.com/SAP/node-hdb) to run tests and examples locally:

Introduction
Getting started
------------
A very simple example how to use this module:
If you do not have access to a SAP HANA server, go to the [SAP HANA Developer Center](http://scn.sap.com/community/developer-center/hana) and choose one of the options to [get your own trial SAP HANA Server](http://scn.sap.com/docs/DOC-31722).
This is a very simple example how to use this module:
```js

@@ -55,20 +74,7 @@ var hdb = require('hdb');

Authentication methods
----------------------
Establish a database connection
-------------------------------
The SAP HANA Database supports the following authentication methods:
The first step to establish a database connection is to create a client object. It is recommended to pass all required `connect` options like `host`, `port`, `user` and `password` to the `createClient` function. They will be used as defaults for following connect calls on the created client instance.
- **SCRAMSHA256** user/password based authentication method
- _GSS_
- _SAML_
Currently only the SCRAMSHA256 authentication method is supported.
Establishing a connection to the database
-----------------------------------------
In order to be able to handle connection errors it is recommended to explicitly
establish a connection using the `connect` method of the client object.
```js

@@ -80,19 +86,66 @@ var hdb = require('hdb');

user : 'user',
password : 'secret'
password : 'secret'
});
console.log(client.readyState); // new
```
client.connect({
user : 'somebody',
password : 'abc123'
}, function (err) {
When a client instance is created it does not immediately open a network connection to the database host. Initially the client is in state `new`. When you call `connect` the first time two things are done internally.
1. A network connection is established and the communication is initialized (Protocol - and Product Version exchange). Now the connection is ready for exchanging messages but no user session is established. The client is in state `disconnected`. This step is skipped if the client is already in state `disconnected`.
2. The authentication process is initiated. After a successful user authentication a database session is established and the client is in state `connected`. If authentication fails the client remains in state `'disconnect'`.
```js
client.connect(function (err) {
if (err) {
return console.error('Client connection error:', err);
return console.error('Error:', err);
}
console.log('Client connected!');
console.log(client.readyState); // connected
});
```
If user and password are specified it will override the defaults of the client. It is possible to disconnect and reconnect with a different user on the same client instance and the same network connection.
If user and password are specified they will override the defaults of the client. It is possible to disconnect and reconnect with a different user on the same client instance and the same network connection.
### Authentication mechanisms
Details about the different authentication method can be found in the [SAP HANA Security Guide](http://help.sap.com/hana/SAP_HANA_Security_Guide_en.pdf).
#### User / Password
Users authenticate themselves with their database `user` and `password`.
#### SAML assertion
SAML bearer assertions as well as unsolicited SAML responses that include an
unencrypted SAML assertion can be used to authenticate users. SAML assertions and responses must be signed using XML signatures. XML Digital signatures can be created with [xml-crypto](https://www.npmjs.org/package/xml-crypto) or [xml-dsig](https://www.npmjs.org/package/xml-dsig).
Instead of `user` and `password` you have to provide a SAML `assertion`.
```js
client.connect({
assertion: '<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ...>...</Assertion>'
},function (err) {
if (err) {
return console.error('Error:', err);
}
console.log('User:', client.get('user'));
console.log('SessionCookie:', client.get('SessionCookie'));
});
```
After a successful SAML authentication the server returns the database `user` and a `SessionCookie` which can be used for reconnect.
#### Kerberos
A Kerberos authentication provider can be used to authenticate users.
> This mechanism is currently not implemented. Please contact me if you require Kerberos based authentication.
### Encrypted network communication
To establish an encrypted database connection just pass whether `key`, `cert` and `ca` or a `pfx` to createClient.
```js
var client = hdb.createClient({
host : 'hostname',
port : 30015,
key : fs.readFileSync('client-key.pem'),
cert : fs.readFileSync('client-cert.pem'),
ca : [fs.readFileSync('trusted-cert.pem')],
...
});
```
Direct Statement Execution
Direct Statement Execution
--------------------------

@@ -103,5 +156,2 @@

Generally we return the statement execution results using callbacks.
For callbacks we follow the convention described in the
[Node.js Style Guide](http://nodeguide.com/style.html#callbacks)
to reserve the first parameter of any callback for an optional error object.
The type of returned result depends on the kind of statement.

@@ -137,3 +187,3 @@

The `exec` function is a convinient way to completely retrieve the result of a query. In this case all selected `rows` are fetched and returned in the callback. The `resultSet` is automatically closed and all `Lobs` are completely read and returned as Buffer objects. If streaming of the results is required you will have to use the `execute` function. This is described in section [Streaming results](#streaming-results).
The `exec` function is a convenient way to completely retrieve the result of a query. In this case all selected `rows` are fetched and returned in the callback. The `resultSet` is automatically closed and all `Lobs` are completely read and returned as Buffer objects. If streaming of the results is required you will have to use the `execute` function. This is described in section [Streaming results](#streaming-results).

@@ -303,3 +353,3 @@ ```js

Streaming Large Objects (LOBs)
Streaming Large Objects
-------------

@@ -332,3 +382,3 @@

For the acceptance tests a database connection has to be established. Therefore you need to copy the configuration template [config.tpl.json](https://github.com/SAP/node-hdb/blob/master/test/lib/config.tpl.json) in the ```test/lib``` folder to ```config.json``` and change the connection data to yours. If the ```config.json``` file does not exist a local mock server is started.
For the acceptance tests a database connection has to be established. Therefore you need to copy the configuration template [config.tpl.json](https://github.com/SAP/node-hdb/blob/master/test/db/config.tpl.json) in the ```test/db``` folder to ```config.json``` and change the connection data to yours. If the ```config.json``` file does not exist a local mock server is started.

@@ -339,3 +389,3 @@

Also, for the examples you need a valid a ```config.json``` in the ```test/lib``` folder.
Also, for the examples you need a valid a ```config.json``` in the ```test/db``` folder.

@@ -350,2 +400,3 @@

- [app7](https://github.com/SAP/node-hdb/blob/master/examples/app7.js): Insert a row with a large image into a db table (uses WriteLobRequest and Transaction internally).
- [app8](https://github.com/SAP/node-hdb/blob/master/examples/app8.js): Automatic reconnect when network connection is lost.
- [call1](https://github.com/SAP/node-hdb/blob/master/examples/call1.js): Call stored procedure.

@@ -357,3 +408,3 @@ - [call2](https://github.com/SAP/node-hdb/blob/master/examples/call2.js): Call stored procedure with lob input and output parameter.

To call e.g. the first example:
To run e.g. the first example:

@@ -368,4 +419,3 @@ ```bash

* Improve error handling
* SAML Authentication support
* Enhance tests
* Increase test coverage
* ...
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc