tedious
Version:
A TDS driver, for connecting to MS SQLServer databases.
233 lines (195 loc) • 6.12 kB
JavaScript
// Generated by CoffeeScript 1.7.1
var DEFAULT_PACKETID, DEFAULT_SPID, DEFAULT_WINDOW, HEADER_LENGTH, NL, OFFSET, Packet, STATUS, TYPE, isPacketComplete, name, packetLength, sprintf, typeByValue, value;
require('./buffertools');
sprintf = require('sprintf').sprintf;
HEADER_LENGTH = 8;
TYPE = {
SQL_BATCH: 0x01,
RPC_REQUEST: 0x03,
TABULAR_RESULT: 0x04,
ATTENTION: 0x06,
BULK_LOAD: 0x07,
TRANSACTION_MANAGER: 0x0E,
LOGIN7: 0x10,
NTLMAUTH_PKT: 0x11,
PRELOGIN: 0x12
};
typeByValue = {};
for (name in TYPE) {
value = TYPE[name];
typeByValue[value] = name;
}
STATUS = {
NORMAL: 0x00,
EOM: 0x01,
IGNORE: 0x02,
RESETCONNECTION: 0x08,
RESETCONNECTIONSKIPTRAN: 0x10
};
OFFSET = {
Type: 0,
Status: 1,
Length: 2,
SPID: 4,
PacketID: 6,
Window: 7
};
DEFAULT_SPID = 0;
DEFAULT_PACKETID = 1;
DEFAULT_WINDOW = 0;
NL = '\n';
Packet = (function() {
function Packet(typeOrBuffer) {
var type;
if (typeOrBuffer instanceof Buffer) {
this.buffer = typeOrBuffer;
} else {
type = typeOrBuffer;
this.buffer = new Buffer(HEADER_LENGTH);
this.buffer.writeUInt8(type, OFFSET.Type);
this.buffer.writeUInt8(STATUS.NORMAL, OFFSET.Status);
this.buffer.writeUInt16BE(DEFAULT_SPID, OFFSET.SPID);
this.buffer.writeUInt8(DEFAULT_PACKETID, OFFSET.PacketID);
this.buffer.writeUInt8(DEFAULT_WINDOW, OFFSET.Window);
this.setLength();
}
}
Packet.prototype.setLength = function() {
return this.buffer.writeUInt16BE(this.buffer.length, OFFSET.Length);
};
Packet.prototype.length = function() {
return this.buffer.readUInt16BE(OFFSET.Length);
};
Packet.prototype.resetConnection = function(reset) {
var status;
status = this.buffer.readUInt8(OFFSET.Status);
if (reset) {
status |= STATUS.RESETCONNECTION;
} else {
status &= 0xFF - STATUS.RESETCONNECTION;
}
return this.buffer.writeUInt8(status, OFFSET.Status);
};
Packet.prototype.last = function(last) {
var status;
status = this.buffer.readUInt8(OFFSET.Status);
if (arguments.length > 0) {
if (last) {
status |= STATUS.EOM;
} else {
status &= 0xFF - STATUS.EOM;
}
this.buffer.writeUInt8(status, OFFSET.Status);
}
return this.isLast();
};
Packet.prototype.isLast = function() {
return !!(this.buffer.readUInt8(OFFSET.Status) & STATUS.EOM);
};
Packet.prototype.packetId = function(packetId) {
if (packetId) {
this.buffer.writeUInt8(packetId % 256, OFFSET.PacketID);
}
return this.buffer.readUInt8(OFFSET.PacketID);
};
Packet.prototype.addData = function(data) {
this.buffer = Buffer.concat([this.buffer, data]);
this.setLength();
return this;
};
Packet.prototype.data = function() {
return this.buffer.slice(HEADER_LENGTH);
};
Packet.prototype.type = function() {
return this.buffer.readUInt8(OFFSET.Type);
};
Packet.prototype.statusAsString = function() {
var status, statuses;
status = this.buffer.readUInt8(OFFSET.Status);
statuses = (function() {
var _results;
_results = [];
for (name in STATUS) {
value = STATUS[name];
if (status & value) {
_results.push(name);
} else {
_results.push(void 0);
}
}
return _results;
})();
return statuses.join(' ').trim();
};
Packet.prototype.headerToString = function(indent) {
var text;
indent || (indent = '');
text = sprintf('type:0x%02X(%s), status:0x%02X(%s), length:0x%04X, spid:0x%04X, packetId:0x%02X, window:0x%02X', this.buffer.readUInt8(OFFSET.Type), typeByValue[this.buffer.readUInt8(OFFSET.Type)], this.buffer.readUInt8(OFFSET.Status), this.statusAsString(), this.buffer.readUInt16BE(OFFSET.Length), this.buffer.readUInt16BE(OFFSET.SPID), this.buffer.readUInt8(OFFSET.PacketID), this.buffer.readUInt8(OFFSET.Window));
return indent + text;
};
Packet.prototype.dataToString = function(indent) {
var BYTES_PER_GROUP, BYTES_PER_LINE, CHARS_PER_GROUP, chars, data, dataDump, offset, _i, _ref;
BYTES_PER_GROUP = 0x04;
CHARS_PER_GROUP = 0x08;
BYTES_PER_LINE = 0x20;
indent || (indent = '');
data = this.data();
dataDump = '';
chars = '';
for (offset = _i = 0, _ref = data.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; offset = 0 <= _ref ? ++_i : --_i) {
if (offset % BYTES_PER_LINE === 0) {
dataDump += indent;
dataDump += sprintf('%04X ', offset);
}
if (data[offset] < 0x20 || data[offset] > 0x7E) {
chars += '.';
if (((offset + 1) % CHARS_PER_GROUP === 0) && !((offset + 1) % BYTES_PER_LINE === 0)) {
chars += ' ';
}
} else {
chars += String.fromCharCode(data[offset]);
}
if (data[offset] != null) {
dataDump += sprintf('%02X', data[offset]);
}
if (((offset + 1) % BYTES_PER_GROUP === 0) && !((offset + 1) % BYTES_PER_LINE === 0)) {
dataDump += ' ';
}
if ((offset + 1) % BYTES_PER_LINE === 0) {
dataDump += ' ' + chars;
chars = '';
if (offset < data.length - 1) {
dataDump += NL;
}
}
}
if (chars.length) {
dataDump += ' ' + chars;
}
return dataDump;
};
Packet.prototype.toString = function(indent) {
indent || (indent = '');
return this.headerToString(indent) + '\n' + this.dataToString(indent + indent);
};
Packet.prototype.payloadString = function(indent) {
return "";
};
return Packet;
})();
isPacketComplete = function(potentialPacketBuffer) {
if (potentialPacketBuffer.length < HEADER_LENGTH) {
return false;
} else {
return potentialPacketBuffer.length >= potentialPacketBuffer.readUInt16BE(OFFSET.Length);
}
};
packetLength = function(potentialPacketBuffer) {
return potentialPacketBuffer.readUInt16BE(OFFSET.Length);
};
exports.Packet = Packet;
exports.OFFSET = OFFSET;
exports.TYPE = TYPE;
exports.isPacketComplete = isPacketComplete;
exports.packetLength = packetLength;
exports.HEADER_LENGTH = HEADER_LENGTH;