From c1b5fe2ab054d6a74e4209280714a7e7596b2792 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Mar 2011 20:04:59 +0000 Subject: [PATCH] native 'notify' and 'notification' events --- lib/client.js | 8 +----- src/binding.cc | 34 +++++++++++++++++-------- test/integration/client/notice-tests.js | 7 ++++- test/unit/client/notification-tests.js | 6 ++--- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/lib/client.js b/lib/client.js index 98e454bc..8febca0e 100644 --- a/lib/client.js +++ b/lib/client.js @@ -23,12 +23,6 @@ var Client = function(config) { this.password = config.password || defaults.password; this.encoding = 'utf8'; var self = this; -<<<<<<< HEAD - this.connection.on('notification', function(msg) { - self.emit('notification', msg); - }) -======= ->>>>>>> master }; sys.inherits(Client, EventEmitter); @@ -90,7 +84,7 @@ p.connect = function() { con.sync(); } }); - + self.emit('connect'); con.on('notification', function(msg) { diff --git a/src/binding.cc b/src/binding.cc index fdec87ea..c5aad018 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -18,6 +18,7 @@ static Persistent connect_symbol; static Persistent error_symbol; static Persistent ready_symbol; static Persistent row_symbol; +static Persistent notice_symbol; class Connection : public EventEmitter { @@ -37,6 +38,7 @@ public: connect_symbol = NODE_PSYMBOL("connect"); error_symbol = NODE_PSYMBOL("_error"); ready_symbol = NODE_PSYMBOL("_readyForQuery"); + notice_symbol = NODE_PSYMBOL("notice"); row_symbol = NODE_PSYMBOL("_row"); NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect); @@ -242,7 +244,7 @@ protected: assert(PQisnonblocking(connection_)); - PQsetNoticeReceiver(connection_, NoticeReceiver, this); + PQsetNoticeProcessor(connection_, NoticeReceiver, this); TRACE("Setting watchers to socket"); ev_io_set(&read_watcher_, fd, EV_READ); @@ -255,24 +257,22 @@ protected: return true; } - static void NoticeReceiver(void *arg, const PGresult *res) + static void NoticeReceiver(void *arg, const char *message) { Connection *self = (Connection*)arg; - self->HandleNotice(res); + self->HandleNotice(message); } - void HandleNotice(const PGresult *res) + void HandleNotice(const char *message) { - LOG("Need to handle notification messages properly"); + HandleScope scope; + Handle notice = String::New(message); + Emit(notice_symbol, 1, ¬ice); } //called to process io_events from libev void HandleIOEvent(int revents) { - //declare handlescope as this method is entered via a libev callback - //and not part of the public v8 interface - HandleScope scope; - if(revents & EV_ERROR) { LOG("Connection error."); return; @@ -291,19 +291,31 @@ protected: return; } + //declare handlescope as this method is entered via a libev callback + //and not part of the public v8 interface + HandleScope scope; + if (PQisBusy(connection_) == 0) { PGresult *result; + bool didHandleResult = false; while ((result = PQgetResult(connection_))) { HandleResult(result); + didHandleResult = true; PQclear(result); } - Emit(ready_symbol, 0, NULL); + if(didHandleResult) { + //might have fired from notification + Emit(ready_symbol, 0, NULL); + } } //TODO look at this later PGnotify *notify; while ((notify = PQnotifies(connection_))) { - LOG("Unhandled (not implemented) Notification received...."); + Local result = Object::New(); + result->Set(String::New("channel"), String::New(notify->relname)); + Handle res = (Handle)result; + Emit((Handle)String::New("notification"), 1, &res); PQfreemem(notify); } diff --git a/test/integration/client/notice-tests.js b/test/integration/client/notice-tests.js index b3c5f434..b78ac6e0 100644 --- a/test/integration/client/notice-tests.js +++ b/test/integration/client/notice-tests.js @@ -4,7 +4,10 @@ test('emits notice message', function() { client.query('create temp table boom(id serial, size integer)'); assert.emits(client, 'notice', function(notice) { assert.ok(notice != null); - client.end(); + //TODO ending connection after notice generates weird errors + process.nextTick(function() { + client.end(); + }) }); }) @@ -15,9 +18,11 @@ test('emits notify message', function() { otherClient.query('LISTEN boom', assert.calls(function() { client.query('NOTIFY boom'); assert.emits(client, 'notification', function(msg) { + assert.equal(msg.channel, 'boom'); client.end() }); assert.emits(otherClient, 'notification', function(msg) { + assert.equal(msg.channel, 'boom'); otherClient.end(); }); })); diff --git a/test/unit/client/notification-tests.js b/test/unit/client/notification-tests.js index b2960d69..24d74604 100644 --- a/test/unit/client/notification-tests.js +++ b/test/unit/client/notification-tests.js @@ -1,9 +1,9 @@ var helper = require(__dirname + "/test-helper"); test('passes connection notification', function() { - var client = new Client(); - assert.emits(client, 'notification', function(msg) { + var client = helper.client(); + assert.emits(client, 'notice', function(msg) { assert.equal(msg, "HAY!!"); }) - client.connection.emit('notification', "HAY!!"); + client.connection.emit('notice', "HAY!!"); })