working on getting query to complete
This commit is contained in:
parent
6ba4575385
commit
c68c365478
64
lib/index.js
64
lib/index.js
@ -3,12 +3,14 @@ var sys = require('sys');
|
||||
var net = require('net');
|
||||
var NUL = '\0';
|
||||
|
||||
var chars = Buffer('RSKZ','utf8');
|
||||
var chars = Buffer('RSKZQC','utf8');
|
||||
var UTF8 = {
|
||||
R: chars[0],
|
||||
S: chars[1],
|
||||
K: chars[2],
|
||||
Z: chars[3]
|
||||
Z: chars[3],
|
||||
Q: chars[4],
|
||||
C: chars[5]
|
||||
};
|
||||
|
||||
|
||||
@ -18,6 +20,7 @@ var Client = function(config) {
|
||||
this.user = config.user;
|
||||
this.database = config.database;
|
||||
this.port = config.port || 5432;
|
||||
this.queryQueue = [];
|
||||
};
|
||||
sys.inherits(Client, EventEmitter);
|
||||
|
||||
@ -25,7 +28,6 @@ Client.prototype.connect = function() {
|
||||
var con = net.createConnection(this.port);
|
||||
var self = this;
|
||||
con.on('connect', function() {
|
||||
|
||||
var data = ['user',self.user,'database', self.database,NUL].join(NUL);
|
||||
var dataBuffer = Buffer(data);
|
||||
var fullBuffer = Buffer(8 + dataBuffer.length);
|
||||
@ -38,19 +40,57 @@ Client.prototype.connect = function() {
|
||||
fullBuffer[6] = 0;
|
||||
fullBuffer[7] = 0;
|
||||
fullBuffer.write(data,8);
|
||||
console.log(fullBuffer);
|
||||
con.write(fullBuffer);
|
||||
});
|
||||
con.on('data', function(data) {
|
||||
console.log('data!');
|
||||
console.log(data);
|
||||
var parser = new Parser(data);
|
||||
con.end();
|
||||
var result = parser.parse();
|
||||
result.forEach(function(msg) {
|
||||
console.log(msg);
|
||||
self.emit('message', msg);
|
||||
self.emit(msg.name, msg);
|
||||
});
|
||||
});
|
||||
this.con = con;
|
||||
this.on('ReadyForQuery', function() {
|
||||
self.readyForQuery = true;
|
||||
self.pulseQueryQueue();
|
||||
});
|
||||
this.on('message', function(msg) {
|
||||
console.log(msg.name);
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.query = function(queryText) {
|
||||
this.queryQueue.push(new Query({
|
||||
text: queryText
|
||||
}));
|
||||
this.pulseQueryQueue();
|
||||
};
|
||||
|
||||
Client.prototype.pulseQueryQueue = function() {
|
||||
if(!this.readyForQuery) {
|
||||
return;
|
||||
}
|
||||
var query = this.queryQueue.shift();
|
||||
if(!query) {
|
||||
return;
|
||||
}
|
||||
var txt = query.text + "\0"
|
||||
var queryTextBuffer = Buffer(txt);
|
||||
var len = queryTextBuffer.length+4;
|
||||
var messageBuffer = Buffer(queryTextBuffer.length + 5);
|
||||
messageBuffer[0] = UTF8.Q;
|
||||
messageBuffer[1] = len >>> 24;
|
||||
messageBuffer[2] = len >>> 16;
|
||||
messageBuffer[3] = len >>> 8;
|
||||
messageBuffer[4] = len >>> 0;
|
||||
messageBuffer.write(txt,5);
|
||||
this.con.write(messageBuffer);
|
||||
this.readyForQuery = false;
|
||||
};
|
||||
|
||||
var Query = function(config) {
|
||||
this.text = config.text;
|
||||
};
|
||||
|
||||
var Parser = function(buffer) {
|
||||
@ -83,6 +123,8 @@ p.parseMessage = function() {
|
||||
return this.parseK();
|
||||
case UTF8.Z:
|
||||
return this.parseZ();
|
||||
case UTF8.C:
|
||||
return this.parseC();
|
||||
default:
|
||||
throw new Error("Unsupported message ID: " + Buffer([messageID]).toString('utf8') + " (" + messageID.toString(16) + ")");
|
||||
}
|
||||
@ -116,6 +158,12 @@ p.parseK = function() {
|
||||
return msg;
|
||||
};
|
||||
|
||||
p.parseC = function() {
|
||||
var msg = this.parseStart('CommandComplete');
|
||||
msg.text = this.parseCString();
|
||||
return msg;
|
||||
};
|
||||
|
||||
//parses common start of message packets
|
||||
p.parseStart = function(name) {
|
||||
return {
|
||||
|
@ -20,10 +20,7 @@ assert.equal(client.database, 'hello');
|
||||
assert.equal(client.port, 321);
|
||||
|
||||
client.port = 5432;
|
||||
client.connect(function() {
|
||||
console.log('connected');
|
||||
client.query('select count(*) from items',function(result) {
|
||||
console.log('ran query');
|
||||
});
|
||||
});
|
||||
client.connect();
|
||||
|
||||
var query = client.query('create temporary table bang (id integer)');
|
||||
|
||||
|
@ -1,15 +1,18 @@
|
||||
require(__dirname+'/test-helper');
|
||||
test('Parser on single messages', function() {
|
||||
var authenticationOkBuffer = Buffer([0x52, 00, 00, 00, 08, 00, 00, 00, 00]);
|
||||
var authOkData = [0x52, 00, 00, 00, 08, 00, 00, 00, 00];
|
||||
var authenticationOkBuffer = Buffer(authOkData);
|
||||
|
||||
var firstString = [0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0];
|
||||
var secondString = [0x55, 0x54, 0x46, 0x38, 0];
|
||||
var bytes = [0x53, 0, 0, 0, 0x19].concat(firstString).concat(secondString);
|
||||
var parameterStatusBuffer = Buffer(bytes);
|
||||
var paramStatusData = [0x53, 0, 0, 0, 0x19].concat(firstString).concat(secondString);
|
||||
var parameterStatusBuffer = Buffer(paramStatusData);
|
||||
|
||||
var backendKeyDataBuffer = Buffer([0x4b, 0, 0, 0, 0x0c, 0, 0, 0, 1, 0, 0, 0, 2]);
|
||||
var backendKeyData = [0x4b, 0, 0, 0, 0x0c, 0, 0, 0, 1, 0, 0, 0, 2];
|
||||
var backendKeyDataBuffer = Buffer(backendKeyData);
|
||||
|
||||
var readyForQueryBuffer = Buffer([0x5a, 0, 0, 0, 5, 'I'.charCodeAt(0)])
|
||||
var readyForQueryData = [0x5a, 0, 0, 0, 5, 'I'.charCodeAt(0)];
|
||||
var readyForQueryBuffer = Buffer(readyForQueryData)
|
||||
|
||||
|
||||
var expectedAuthenticationOkayMessage = {
|
||||
@ -60,10 +63,37 @@ test('Parser on single messages', function() {
|
||||
assert.same(result, expectedReadyForQueryMessage);
|
||||
});
|
||||
|
||||
test('parses multiple messages', function() {
|
||||
var message = authOkData
|
||||
.concat(paramStatusData)
|
||||
.concat(backendKeyData)
|
||||
.concat(readyForQueryData);
|
||||
var buffer = Buffer(message);
|
||||
var result = new Parser(buffer).parse();
|
||||
assert.equal(result.length, 4);
|
||||
assert.same(result[0], expectedAuthenticationOkayMessage);
|
||||
assert.same(result[1], expectedParameterStatusMessage);
|
||||
assert.same(result[2], expectedBackendKeyDataMessage);
|
||||
assert.same(result[3], expectedReadyForQueryMessage);
|
||||
});
|
||||
|
||||
test('parses normal CString', function() {
|
||||
var result = new Parser(Buffer([33,0])).parseCString();
|
||||
assert.equal(result,"!");
|
||||
});
|
||||
|
||||
var resultText = stringToHex("SELECT 3\0");
|
||||
var length = resultText.length + 4;
|
||||
var commandCompleteData = [0x43, 0, 0, 0, length].concat(resultText);
|
||||
|
||||
test('parses CommandComplete message', function() {
|
||||
var result = new Parser(Buffer(commandCompleteData)).parse()[0];
|
||||
assert.same(result, {
|
||||
length: 13,
|
||||
id: 'C',
|
||||
text: "SELECT 3"
|
||||
});
|
||||
});
|
||||
|
||||
test('parses empty CString', function() {
|
||||
var result = new Parser(Buffer([0])).parseCString();
|
||||
|
@ -23,7 +23,12 @@ test = function(name, action) {
|
||||
test.tabout = 0;
|
||||
|
||||
stringToHex = function(string) {
|
||||
|
||||
var b = Buffer(string,'utf8');
|
||||
var result = [];
|
||||
for(var i = 0; i < b.length; i++) {
|
||||
result.push(b[i]);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
hexToString = function(hexArray) {
|
||||
|
4
watch.rb
4
watch.rb
@ -3,14 +3,16 @@
|
||||
def run_parser_tests
|
||||
system("node test/parser-tests.js")
|
||||
puts ""
|
||||
puts("waiting...")
|
||||
puts("#{Time.now} waiting...")
|
||||
puts ""
|
||||
end
|
||||
|
||||
watch('lib/(.*)\.js') { |md|
|
||||
puts "lib changed"
|
||||
run_parser_tests
|
||||
}
|
||||
|
||||
watch('test/(.*)\.js') { |md|
|
||||
puts "test changed"
|
||||
run_parser_tests
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user