From 0f0f59c12f064a3223ff91dd3b94ebe041498d3c Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Fri, 18 Feb 2011 11:38:47 -0600 Subject: [PATCH] initial experiment with libpq bindings --- lib/binding.js | 2 + src/binding.cc | 113 ++++++++++++++++++++++++++++++ test/integration/binding-spike.js | 7 ++ wscript | 31 ++++++++ 4 files changed, 153 insertions(+) create mode 100644 lib/binding.js create mode 100644 src/binding.cc create mode 100644 test/integration/binding-spike.js create mode 100644 wscript diff --git a/lib/binding.js b/lib/binding.js new file mode 100644 index 00000000..f2670c15 --- /dev/null +++ b/lib/binding.js @@ -0,0 +1,2 @@ +var binding = require(__dirname + '/../build/default/binding'); +module.exports = binding.Connection; diff --git a/src/binding.cc b/src/binding.cc new file mode 100644 index 00000000..4c10d76a --- /dev/null +++ b/src/binding.cc @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include + +#define LOG(msg) printf("%s\n",msg) + +using namespace v8; +using namespace node; + +class Connection : public EventEmitter { +public: + static void + Init (Handle target) + { + HandleScope scope; + Local t = FunctionTemplate::New(New); + + t->Inherit(EventEmitter::constructor_template); + t->InstanceTemplate()->SetInternalFieldCount(1); + t->SetClassName(String::NewSymbol("Connection")); + + NODE_SET_PROTOTYPE_METHOD(t, "test", Test); + + target->Set(String::NewSymbol("Connection"), t->GetFunction()); + LOG("created class"); + } + + static Handle + Test(const Arguments& args) + { + HandleScope scope; + + PGconn *connection_ = PQconnectStart(""); + + if (!connection_) { + LOG("Connection couldn't be created"); + } else { + LOG("Connect created"); + } + + if (PQsetnonblocking(connection_, 1) == -1) { + LOG("Unable to set connection to non-blocking"); + PQfinish(connection_); + connection_ = NULL; + } + + ConnStatusType status = PQstatus(connection_); + printf("status: %d\n", status); + if(CONNECTION_BAD == status) { + PQfinish(connection_); + LOG("Bad connection status"); + connection_ = NULL; + } + + int fd = PQsocket(connection_); + if(fd < 0) { + LOG("socket fd was negative. error"); + } + + LOG("Initializing ev watchers"); + ev_io read_watcher; + ev_io write_watcher; + ev_init(&read_watcher, io_event); + ev_init(&write_watcher, io_event); + + ev_io_set(&read_watcher, fd, EV_READ); + ev_io_set(&write_watcher, fd, EV_WRITE); + + ev_io_start(EV_DEFAULT_ &write_watcher); + LOG("EV started"); + Local result = String::New("Hello world"); + return scope.Close(result); + } + + static void + io_event(EV_P_ ev_io *w, int revents) + { + LOG("Received IO event"); + } + + Connection () : EventEmitter () + { + } + + ~Connection () + { + } + +protected: + static Handle + New (const Arguments& args) + { + HandleScope scope; + Connection *connection = new Connection(); + connection->Wrap(args.This()); + + return args.This(); + } + +private: + ev_io read_watcher_; + ev_io write_watcher_; + +}; + +extern "C" void +init (Handle target) +{ + HandleScope scope; + Connection::Init(target); +} diff --git a/test/integration/binding-spike.js b/test/integration/binding-spike.js new file mode 100644 index 00000000..8dc35c2d --- /dev/null +++ b/test/integration/binding-spike.js @@ -0,0 +1,7 @@ +var Connection = require(__dirname + "/../../lib/binding"); +var con = new Connection(); +console.log(con.test()); + +setTimeout(function() { + +}, 1000) diff --git a/wscript b/wscript new file mode 100644 index 00000000..363cbda1 --- /dev/null +++ b/wscript @@ -0,0 +1,31 @@ +import Options, Utils +from os import unlink, symlink, popen +from os.path import exists + +srcdir = '.' +blddir = 'build' +VERSION = '0.0.1' + +def set_options(opt): + opt.tool_options('compiler_cxx') + +def configure(conf): + conf.check_tool('compiler_cxx') + conf.check_tool('node_addon') + + pg_config = conf.find_program('pg_config', var='PG_CONFIG', mandatory=True) + pg_libdir = popen("%s --libdir" % pg_config).readline().strip() + conf.env.append_value("LIBPATH_PG", pg_libdir) + conf.env.append_value("LIB_PG", "pq") + pg_includedir = popen("%s --includedir" % pg_config).readline().strip() + conf.env.append_value("CPPPATH_PG", pg_includedir) + +def build(bld): + obj = bld.new_task_gen('cxx', 'shlib', 'node_addon') + obj.cxxflags = ["-g", "-D_LARGEFILE_SOURCE", "-Wall"] + obj.target = 'binding' + obj.source = "./src/binding.cc" + obj.uselib = "PG" + +def test(test): + Utils.exec_command("node test/integration/binding-spike.js")