@@ -104,9 +104,12 @@ Connection::~Connection()
104104*/
105105void Connection::setConnection (dpi::Conn* dpiconn, Oracledb* oracledb)
106106{
107- this ->dpiconn_ = dpiconn;
108- this ->isValid_ = true ;
109- this ->oracledb_ = oracledb;
107+ this ->dpiconn_ = dpiconn;
108+ this ->isValid_ = true ;
109+ this ->oracledb_ = oracledb;
110+ this ->lobCount_ = 0 ;
111+ this ->rsCount_ = 0 ;
112+ this ->dbCount_ = 0 ;
110113}
111114
112115/* ****************************************************************************/
@@ -438,11 +441,10 @@ NAN_METHOD(Connection::Execute)
438441 Connection *connection;
439442 NJS_GET_CALLBACK ( callback, info );
440443
441- eBaton *executeBaton = new eBaton;
442- executeBaton->cb .Reset ( callback );
443- NJS_CHECK_NUMBER_OF_ARGS ( executeBaton->error , info, 2 , 4 , exitExecute );
444444 connection = Nan::ObjectWrap::Unwrap<Connection>(info.This ());
445+ eBaton *executeBaton = new eBaton ( connection->DBCount (), callback );
445446
447+ NJS_CHECK_NUMBER_OF_ARGS ( executeBaton->error , info, 2 , 4 , exitExecute );
446448 NJS_CHECK_OBJECT_VALID3 ( connection, executeBaton->error , exitExecute );
447449
448450 if (!connection->isValid_ )
@@ -479,8 +481,16 @@ NAN_METHOD(Connection::Execute)
479481
480482 exitExecute:
481483 executeBaton->req .data = (void *) executeBaton;
482- uv_queue_work (uv_default_loop (), &executeBaton->req ,
484+ int status = uv_queue_work (uv_default_loop (), &executeBaton->req ,
483485 Async_Execute, (uv_after_work_cb)Async_AfterExecute);
486+ // delete the Baton if uv_queue_work fails
487+ if ( status )
488+ {
489+ delete executeBaton;
490+ string error = NJSMessages::getErrorMsg ( errInternalError,
491+ " uv_queue_work" , " Execute" );
492+ NJS_SET_EXCEPTION (error.c_str (), error.length ());
493+ }
484494
485495 info.GetReturnValue ().SetUndefined ();
486496}
@@ -2053,9 +2063,8 @@ void Connection::Async_AfterExecute(uv_work_t *req)
20532063 }
20542064 argv[1 ] = result;
20552065 }
2056- exitAsyncAfterExecute:
2066+ exitAsyncAfterExecute:
20572067 Local<Function> callback = Nan::New<Function>(executeBaton->cb );
2058- executeBaton->cb .Reset ();
20592068 delete executeBaton;
20602069 Nan::MakeCallback ( Nan::GetCurrentContext ()->Global (), callback, 2 , argv );
20612070 if (tc.HasCaught ())
@@ -2546,6 +2555,33 @@ v8::Local<v8::Value> Connection::GetOutBindObject ( eBaton *executeBaton )
25462555 return scope.Escape (objectBinds);
25472556}
25482557
2558+
2559+ /* ***************************************************************************/
2560+ /* NAME
2561+ * Connection::getConnectionBusyStatus
2562+ *
2563+ * DESCRIPTION
2564+ * Checks whther connection is busy with database call or not using counters
2565+ *
2566+ * PARAMETERS
2567+ * connection - connection object to check it's counters
2568+ *
2569+ * Note: Currently this function can be used only in Release () method
2570+ */
2571+ ConnectionBusyStatus Connection::getConnectionBusyStatus ( Connection *conn )
2572+ {
2573+ ConnectionBusyStatus connStatus = CONN_NOT_BUSY;
2574+
2575+ if ( conn->lobCount_ != 0 )
2576+ connStatus = CONN_BUSY_LOB;
2577+ else if ( conn->rsCount_ != 0 )
2578+ connStatus = CONN_BUSY_RS;
2579+ else if ( conn->dbCount_ != 1 ) // 1 for Release operaion itself
2580+ connStatus = CONN_BUSY_DB;
2581+
2582+ return connStatus;
2583+ }
2584+
25492585/* ****************************************************************************/
25502586/*
25512587 DESCRIPTION
@@ -2560,26 +2596,55 @@ NAN_METHOD(Connection::Release)
25602596 Local<Function> callback;
25612597 Connection *connection;
25622598 NJS_GET_CALLBACK ( callback, info );
2599+ ConnectionBusyStatus connStat;
25632600
2564- eBaton* releaseBaton = new eBaton;
2565- releaseBaton->cb .Reset (callback);
2566-
2567- NJS_CHECK_NUMBER_OF_ARGS ( releaseBaton->error , info, 1 , 1 , exitRelease );
25682601 connection = Nan::ObjectWrap::Unwrap<Connection>(info.This ());
2602+ eBaton *releaseBaton = new eBaton ( connection->DBCount (), callback );
25692603
2604+ NJS_CHECK_NUMBER_OF_ARGS ( releaseBaton->error , info, 1 , 1 , exitRelease );
25702605 NJS_CHECK_OBJECT_VALID3 (connection, releaseBaton->error , exitRelease);
25712606 if (!connection->isValid_ )
25722607 {
25732608 releaseBaton->error = NJSMessages::getErrorMsg ( errInvalidConnection );
25742609 goto exitRelease;
25752610 }
2611+
2612+
2613+ // Check to see if database call is in progress
2614+ connStat = getConnectionBusyStatus ( connection );
2615+ switch ( connStat )
2616+ {
2617+ case CONN_NOT_BUSY:
2618+ break ; // Nothing to do in this case
2619+ case CONN_BUSY_LOB:
2620+ releaseBaton->error = NJSMessages::getErrorMsg ( errBusyConnLOB );
2621+ goto exitRelease;
2622+ case CONN_BUSY_RS:
2623+ releaseBaton->error = NJSMessages::getErrorMsg ( errBusyConnRS );
2624+ goto exitRelease;
2625+ case CONN_BUSY_DB:
2626+ releaseBaton->error = NJSMessages::getErrorMsg ( errBusyConnDB );
2627+ goto exitRelease;
2628+
2629+ default :
2630+ break ;
2631+ }
2632+
25762633 connection->isValid_ = false ;
25772634 releaseBaton->dpiconn = connection->dpiconn_ ;
25782635 exitRelease:
25792636 releaseBaton->req .data = (void *) releaseBaton;
25802637
2581- uv_queue_work (uv_default_loop (), &releaseBaton->req ,
2638+ int status = uv_queue_work (uv_default_loop (), &releaseBaton->req ,
25822639 Async_Release, (uv_after_work_cb)Async_AfterRelease);
2640+ // delete the Baton if uv_queue_work fails
2641+ if ( status )
2642+ {
2643+ delete releaseBaton;
2644+ string error = NJSMessages::getErrorMsg ( errInternalError,
2645+ " uv_queue_work" , " Release" );
2646+ NJS_SET_EXCEPTION (error.c_str (), error.length ());
2647+ }
25832648 info.GetReturnValue ().SetUndefined ();
25842649 scope.Escape ( Nan::Undefined () );
25852650}
@@ -2635,7 +2700,6 @@ void Connection::Async_AfterRelease(uv_work_t *req)
26352700 else
26362701 argv[0 ] = Nan::Undefined ();
26372702 Local<Function> callback = Nan::New<Function>(releaseBaton->cb );
2638- releaseBaton->cb .Reset ();
26392703 delete releaseBaton;
26402704 Nan::MakeCallback ( Nan::GetCurrentContext ()->Global (),
26412705 callback, 1 , argv );
@@ -2660,11 +2724,10 @@ NAN_METHOD(Connection::Commit)
26602724 Connection *connection;
26612725 NJS_GET_CALLBACK ( callback, info );
26622726
2663- eBaton* commitBaton = new eBaton;
2664- commitBaton->cb .Reset ( callback );
2665- NJS_CHECK_NUMBER_OF_ARGS ( commitBaton->error , info, 1 , 1 , exitCommit );
26662727 connection = Nan::ObjectWrap::Unwrap<Connection>(info.This ());
2728+ eBaton *commitBaton = new eBaton ( connection->DBCount (), callback );
26672729
2730+ NJS_CHECK_NUMBER_OF_ARGS ( commitBaton->error , info, 1 , 1 , exitCommit );
26682731 NJS_CHECK_OBJECT_VALID3 ( connection, commitBaton->error , exitCommit );
26692732 if (!connection->isValid_ )
26702733 {
@@ -2675,8 +2738,16 @@ NAN_METHOD(Connection::Commit)
26752738exitCommit:
26762739 commitBaton->req .data = (void *) commitBaton;
26772740
2678- uv_queue_work (uv_default_loop (), &commitBaton->req ,
2741+ int status = uv_queue_work (uv_default_loop (), &commitBaton->req ,
26792742 Async_Commit, (uv_after_work_cb)Async_AfterCommit);
2743+ // delete the Baton if uv_queue_work fails
2744+ if ( status )
2745+ {
2746+ delete commitBaton;
2747+ string error = NJSMessages::getErrorMsg ( errInternalError,
2748+ " uv_queue_work" , " Commit" );
2749+ NJS_SET_EXCEPTION (error.c_str (), error.length ());
2750+ }
26802751
26812752 info.GetReturnValue ().SetUndefined ();
26822753}
@@ -2732,14 +2803,15 @@ void Connection::Async_AfterCommit (uv_work_t *req)
27322803 else
27332804 argv[0 ] = Nan::Undefined ();
27342805
2806+ Local<Function> callback = Nan::New<Function>(commitBaton->cb );
2807+ delete commitBaton;
27352808 Nan::MakeCallback ( Nan::GetCurrentContext ()->Global (),
2736- Nan::New<Function>(commitBaton->cb ), 1 , argv );
2809+ callback, 1 , argv );
2810+
27372811 if (tc.HasCaught ())
27382812 {
27392813 Nan::FatalException (tc);
27402814 }
2741- commitBaton->cb .Reset ();
2742- delete commitBaton;
27432815}
27442816
27452817/* ****************************************************************************/
@@ -2756,10 +2828,9 @@ NAN_METHOD(Connection::Rollback)
27562828 Connection *connection;
27572829 NJS_GET_CALLBACK ( callback, info );
27582830
2759- eBaton* rollbackBaton = new eBaton;
2760- rollbackBaton->cb .Reset ( callback );
2761- NJS_CHECK_NUMBER_OF_ARGS ( rollbackBaton->error , info, 1 , 1 , exitRollback );
27622831 connection = Nan::ObjectWrap::Unwrap<Connection>(info.This ());
2832+ eBaton *rollbackBaton = new eBaton ( connection->DBCount (), callback );
2833+ NJS_CHECK_NUMBER_OF_ARGS ( rollbackBaton->error , info, 1 , 1 , exitRollback );
27632834 NJS_CHECK_OBJECT_VALID3 ( connection, rollbackBaton->error , exitRollback );
27642835
27652836 if (!connection->isValid_ )
@@ -2770,8 +2841,16 @@ NAN_METHOD(Connection::Rollback)
27702841 rollbackBaton->dpiconn = connection->dpiconn_ ;
27712842 exitRollback:
27722843 rollbackBaton->req .data = (void *) rollbackBaton;
2773- uv_queue_work (uv_default_loop (), &rollbackBaton->req ,
2774- Async_Rollback, (uv_after_work_cb)Async_AfterRollback);
2844+ int status = uv_queue_work (uv_default_loop (), &rollbackBaton->req ,
2845+ Async_Rollback, (uv_after_work_cb)Async_AfterRollback);
2846+ // delete the Baton if uv_queue_work fails
2847+ if ( status )
2848+ {
2849+ delete rollbackBaton;
2850+ string error = NJSMessages::getErrorMsg ( errInternalError,
2851+ " uv_queue_work" , " Rollback" );
2852+ NJS_SET_EXCEPTION (error.c_str (), error.length ());
2853+ }
27752854 info.GetReturnValue ().SetUndefined ();
27762855}
27772856
@@ -2826,14 +2905,14 @@ void Connection::Async_AfterRollback(uv_work_t *req)
28262905 else
28272906 argv[0 ] = Nan::Undefined ();
28282907
2908+ Local<Function> callback = Nan::New<Function>(rollbackBaton->cb );
2909+ delete rollbackBaton;
28292910 Nan::MakeCallback ( Nan::GetCurrentContext ()->Global (),
2830- Nan::New<Function>(rollbackBaton-> cb ) , 1 , argv );
2911+ callback , 1 , argv );
28312912 if (tc.HasCaught ())
28322913 {
28332914 Nan::FatalException (tc);
28342915 }
2835- rollbackBaton->cb .Reset ();
2836- delete rollbackBaton;
28372916}
28382917
28392918/* ****************************************************************************/
@@ -2850,11 +2929,10 @@ NAN_METHOD(Connection::Break)
28502929 Connection *connection;
28512930 NJS_GET_CALLBACK ( callback, info );
28522931
2853- eBaton* breakBaton = new eBaton;
2854- breakBaton->cb .Reset ( callback );
2855- NJS_CHECK_NUMBER_OF_ARGS ( breakBaton->error , info, 1 , 1 , exitBreak );
28562932 connection = Nan::ObjectWrap::Unwrap<Connection>(info.This ());
2933+ eBaton *breakBaton = new eBaton ( connection->DBCount (), callback );
28572934
2935+ NJS_CHECK_NUMBER_OF_ARGS ( breakBaton->error , info, 1 , 1 , exitBreak );
28582936 NJS_CHECK_OBJECT_VALID3 ( connection, breakBaton->error , exitBreak );
28592937
28602938 if (!connection->isValid_ )
@@ -2866,8 +2944,16 @@ NAN_METHOD(Connection::Break)
28662944 exitBreak:
28672945 breakBaton->req .data = (void *) breakBaton;
28682946
2869- uv_queue_work (uv_default_loop (), &breakBaton->req ,
2947+ int status = uv_queue_work (uv_default_loop (), &breakBaton->req ,
28702948 Async_Break, (uv_after_work_cb)Async_AfterBreak);
2949+ // delete the Baton if uv_queue_work fails
2950+ if ( status )
2951+ {
2952+ delete breakBaton;
2953+ string error = NJSMessages::getErrorMsg ( errInternalError,
2954+ " uv_queue_work" , " Break" );
2955+ NJS_SET_EXCEPTION (error.c_str (), error.length ());
2956+ }
28712957
28722958 info.GetReturnValue ().SetUndefined ();
28732959}
@@ -2923,14 +3009,14 @@ void Connection::Async_AfterBreak (uv_work_t *req)
29233009 argv[0 ] = v8::Exception::Error (Nan::New<v8::String>((breakBaton->error ).c_str ()).ToLocalChecked ());
29243010 else
29253011 argv[0 ] = Nan::Undefined ();
3012+ Local<Function> callback = Nan::New<Function>(breakBaton->cb );
3013+ delete breakBaton;
29263014 Nan::MakeCallback ( Nan::GetCurrentContext ()->Global (),
2927- Nan::New<Function>(breakBaton-> cb ) , 1 , argv );
3015+ callback , 1 , argv );
29283016 if (tc.HasCaught ())
29293017 {
29303018 Nan::FatalException (tc);
29313019 }
2932- breakBaton->cb .Reset ();
2933- delete breakBaton;
29343020}
29353021
29363022/* ***************************************************************************/
0 commit comments