include command metadata with native query result callback - closes #128
This commit is contained in:
parent
7f00b3ee30
commit
176e6c7ab2
@ -132,6 +132,14 @@ var clientBuilder = function(config) {
|
||||
connection._activeQuery.handleRow(row);
|
||||
});
|
||||
|
||||
connection.on('_cmdStatus', function(status) {
|
||||
var meta = {
|
||||
};
|
||||
meta.command = status.command.split(' ')[0];
|
||||
meta.rowCount = parseInt(status.value);
|
||||
connection._lastMeta = meta;
|
||||
});
|
||||
|
||||
//TODO: emit more native error properties (make it match js error)
|
||||
connection.on('_error', function(err) {
|
||||
//create Error object from object literal
|
||||
@ -156,7 +164,7 @@ var clientBuilder = function(config) {
|
||||
this._namedQuery = false;
|
||||
this._sendQueryPrepared(q.name, q.values||[]);
|
||||
} else {
|
||||
connection._activeQuery.handleReadyForQuery();
|
||||
connection._activeQuery.handleReadyForQuery(connection._lastMeta);
|
||||
connection._activeQuery = null;
|
||||
connection._pulseQueryQueue();
|
||||
}
|
||||
|
@ -82,9 +82,10 @@ p.handleError = function(error) {
|
||||
}
|
||||
}
|
||||
|
||||
p.handleReadyForQuery = function() {
|
||||
p.handleReadyForQuery = function(meta) {
|
||||
if(this.callback) {
|
||||
this.callback(null, { rows: this.rows });
|
||||
(meta || {}).rows = this.rows;
|
||||
this.callback(null, meta);
|
||||
}
|
||||
this.emit('end');
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ static Persistent<String> type_symbol;
|
||||
static Persistent<String> channel_symbol;
|
||||
static Persistent<String> payload_symbol;
|
||||
static Persistent<String> emit_symbol;
|
||||
static Persistent<String> command_symbol;
|
||||
|
||||
class Connection : public ObjectWrap {
|
||||
|
||||
@ -62,6 +63,7 @@ public:
|
||||
type_symbol = NODE_PSYMBOL("type");
|
||||
channel_symbol = NODE_PSYMBOL("channel");
|
||||
payload_symbol = NODE_PSYMBOL("payload");
|
||||
command_symbol = NODE_PSYMBOL("command");
|
||||
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect);
|
||||
@ -437,19 +439,22 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void HandleResult(const PGresult* result)
|
||||
void HandleResult(PGresult* result)
|
||||
{
|
||||
ExecStatusType status = PQresultStatus(result);
|
||||
switch(status) {
|
||||
case PGRES_TUPLES_OK:
|
||||
HandleTuplesResult(result);
|
||||
{
|
||||
HandleTuplesResult(result);
|
||||
EmitCommandMetaData(result);
|
||||
}
|
||||
break;
|
||||
case PGRES_FATAL_ERROR:
|
||||
HandleErrorResult(result);
|
||||
break;
|
||||
case PGRES_COMMAND_OK:
|
||||
case PGRES_EMPTY_QUERY:
|
||||
//do nothing
|
||||
case PGRES_EMPTY_QUERY:
|
||||
EmitCommandMetaData(result);
|
||||
break;
|
||||
default:
|
||||
printf("Unrecogized query status: %s\n", PQresStatus(status));
|
||||
@ -457,12 +462,23 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void EmitCommandMetaData(PGresult* result)
|
||||
{
|
||||
HandleScope scope;
|
||||
Local<Object> info = Object::New();
|
||||
info->Set(command_symbol, String::New(PQcmdStatus(result)));
|
||||
info->Set(value_symbol, String::New(PQcmdTuples(result)));
|
||||
Handle<Value> e = (Handle<Value>)info;
|
||||
Emit("_cmdStatus", &e);
|
||||
}
|
||||
|
||||
//maps the postgres tuple results to v8 objects
|
||||
//and emits row events
|
||||
//TODO look at emitting fewer events because the back & forth between
|
||||
//javascript & c++ might introduce overhead (requires benchmarking)
|
||||
void HandleTuplesResult(const PGresult* result)
|
||||
{
|
||||
HandleScope scope;
|
||||
int rowCount = PQntuples(result);
|
||||
for(int rowNumber = 0; rowNumber < rowCount; rowNumber++) {
|
||||
//create result object for this row
|
||||
@ -489,7 +505,6 @@ protected:
|
||||
row->Set(Integer::New(fieldNumber), field);
|
||||
}
|
||||
|
||||
//not sure about what to dealloc or scope#Close here
|
||||
Handle<Value> e = (Handle<Value>)row;
|
||||
Emit("_row", &e);
|
||||
}
|
||||
@ -564,30 +579,30 @@ private:
|
||||
{
|
||||
PostgresPollingStatusType status = PQconnectPoll(connection_);
|
||||
switch(status) {
|
||||
case PGRES_POLLING_READING:
|
||||
TRACE("Polled: PGRES_POLLING_READING");
|
||||
StopWrite();
|
||||
StartRead();
|
||||
break;
|
||||
case PGRES_POLLING_WRITING:
|
||||
TRACE("Polled: PGRES_POLLING_WRITING");
|
||||
StopRead();
|
||||
StartWrite();
|
||||
break;
|
||||
case PGRES_POLLING_FAILED:
|
||||
StopRead();
|
||||
StopWrite();
|
||||
TRACE("Polled: PGRES_POLLING_FAILED");
|
||||
EmitLastError();
|
||||
break;
|
||||
case PGRES_POLLING_OK:
|
||||
TRACE("Polled: PGRES_POLLING_OK");
|
||||
connecting_ = false;
|
||||
StartRead();
|
||||
Emit("connect");
|
||||
default:
|
||||
//printf("Unknown polling status: %d\n", status);
|
||||
break;
|
||||
case PGRES_POLLING_READING:
|
||||
TRACE("Polled: PGRES_POLLING_READING");
|
||||
StopWrite();
|
||||
StartRead();
|
||||
break;
|
||||
case PGRES_POLLING_WRITING:
|
||||
TRACE("Polled: PGRES_POLLING_WRITING");
|
||||
StopRead();
|
||||
StartWrite();
|
||||
break;
|
||||
case PGRES_POLLING_FAILED:
|
||||
StopRead();
|
||||
StopWrite();
|
||||
TRACE("Polled: PGRES_POLLING_FAILED");
|
||||
EmitLastError();
|
||||
break;
|
||||
case PGRES_POLLING_OK:
|
||||
TRACE("Polled: PGRES_POLLING_OK");
|
||||
connecting_ = false;
|
||||
StartRead();
|
||||
Emit("connect");
|
||||
default:
|
||||
//printf("Unknown polling status: %d\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,25 +2,21 @@ var helper = require(__dirname + "/test-helper");
|
||||
var pg = helper.pg;
|
||||
|
||||
test('should return insert metadata', function() {
|
||||
return false;
|
||||
pg.connect(helper.config, assert.calls(function(err, client) {
|
||||
assert.isNull(err);
|
||||
client.query("CREATE TEMP TABLE zugzug(name varchar(10))", assert.calls(function(err, result) {
|
||||
assert.isNull(err);
|
||||
//let's list this as ignored for now
|
||||
// process.nextTick(function() {
|
||||
// test('should identify "CREATE TABLE" message', function() {
|
||||
// return false;
|
||||
// assert.equal(result.command, "CREATE TABLE");
|
||||
// assert.equal(result.rowCount, 0);
|
||||
// })
|
||||
// })
|
||||
assert.equal(result.oid, null);
|
||||
assert.equal(result.command, 'CREATE');
|
||||
client.query("INSERT INTO zugzug(name) VALUES('more work?')", assert.calls(function(err, result) {
|
||||
assert.equal(result.command, "INSERT");
|
||||
assert.equal(result.rowCount, 1);
|
||||
process.nextTick(client.end.bind(client));
|
||||
return false;
|
||||
client.query('SELECT * FROM zugzug', assert.calls(function(err, result) {
|
||||
assert.isNull(err);
|
||||
assert.equal(result.rowCount, 1);
|
||||
assert.equal(result.command, 'SELECT');
|
||||
process.nextTick(pg.end.bind(pg));
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
|
Loading…
Reference in New Issue
Block a user