Skip to content

Commit

Permalink
Implement connection.isConnected(), don't segfault when doing work on…
Browse files Browse the repository at this point in the history
… closed connection

We need to be able to detect closed connections so that we can more easily integrate with generic-pool.  That module
has a validate() hook which pairs nicely with the connection.isConnected() change I'm proposing here.

Test scenario for reproing segfault issue:
* Open connection
* Set timer for closing connection with connection.close() after 10 seconds
* Wait for timer to activate and close connection
* Try to run connection.execute('SELECT 1 FROM DUAL')
* Segfault occurs
* After this change, it will throw an error instead of segfaulting
  • Loading branch information
mwolson committed Jun 29, 2013
1 parent 31acca2 commit f0a1fb4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ oracle.connect(connData, function(err, connection) {
});
```

To validate whether the connection is still established after some time:

```javascript
if (! connection.isConnected()) {
// retire this connection from a pool
}
```


## Out Params
Expand Down
18 changes: 17 additions & 1 deletion src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ void Connection::Init(Handle<Object> target) {

NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "execute", Execute);
NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "close", Close);
NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "isConnected", IsConnected);
NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "setAutoCommit", SetAutoCommit);
NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "commit", Commit);
NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "rollback", Rollback);
Expand Down Expand Up @@ -85,6 +86,16 @@ Handle<Value> Connection::Close(const Arguments& args) {
}
}

Handle<Value> Connection::IsConnected(const Arguments& args) {
Connection* connection = ObjectWrap::Unwrap<Connection>(args.This());

if(connection && connection->m_connection) {
return Boolean::New(true);
} else {
return Boolean::New(false);
}
}

Handle<Value> Connection::Commit(const Arguments& args) {
Connection* connection = ObjectWrap::Unwrap<Connection>(args.This());

Expand Down Expand Up @@ -368,6 +379,9 @@ void Connection::EIO_Execute(uv_work_t* req) {
oracle::occi::Statement* stmt = NULL;
oracle::occi::ResultSet* rs = NULL;
try {
if(! baton->connection->m_connection) {
throw NodeOracleException("Connection already closed");
}
stmt = baton->connection->m_connection->createStatement(baton->sql);
stmt->setAutoCommit(baton->connection->m_autoCommit);
int outputParam = SetValuesOnStatement(stmt, baton->values);
Expand Down Expand Up @@ -444,7 +458,9 @@ void Connection::EIO_Execute(uv_work_t* req) {
rs = NULL;
}
if(stmt) {
baton->connection->m_connection->terminateStatement(stmt);
if(baton->connection->m_connection) {
baton->connection->m_connection->terminateStatement(stmt);
}
stmt = NULL;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Connection : ObjectWrap {
static Handle<Value> New(const Arguments& args);
static Handle<Value> Execute(const Arguments& args);
static Handle<Value> Close(const Arguments& args);
static Handle<Value> IsConnected(const Arguments& args);
static Handle<Value> Commit(const Arguments& args);
static Handle<Value> Rollback(const Arguments& args);
static Handle<Value> SetAutoCommit(const Arguments& args);
Expand Down

0 comments on commit f0a1fb4

Please sign in to comment.