@@ -75,9 +75,6 @@ Nan::Persistent<FunctionTemplate> Connection::connectionTemplate_s;
7575 #define NJS_ITER_SIZE 65535 /* Use (64KB - 1) with 11g Clients */
7676#endif
7777
78- // Max number of bytes allowed for PLSQL STRING/BUFFER arguments
79- #define NJS_THRESHOLD_SIZE_PLSQL_STRING_ARG 32767
80-
8178// number of rows prefetched by non-ResultSet queries
8279#define NJS_PREFETCH_NON_RESULTSET 2
8380
@@ -1088,6 +1085,7 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
10881085 {
10891086 case NJS_VALUETYPE_NULL:
10901087 bind->value = NULL ;
1088+ *(bind->len ) = 0 ; /* NULL value provided, no buffer used */
10911089 bind->type = dpi::DpiVarChar;
10921090 break ;
10931091
@@ -2403,41 +2401,17 @@ void Connection::Descr2StringOrBuffer ( eBaton* executeBaton )
24032401 * index - Index of the Bind vector
24042402 *
24052403 * NOTE:
2406- * Bind enhancements for CLOB/BLOB As String/Buffer not supported for INOUT
2407- * arguments
2404+ * Bind type is expected only STRING and RAW
24082405 *
24092406 */
24102407void Connection::ConvertStringOrBuffer2LOB ( eBaton* executeBaton,
24112408 unsigned int index )
24122409{
24132410 Bind *bind = executeBaton->binds [index];
2414- DPI_SZ_TYPE size = 0 ;
24152411
2416- if ( !bind->isOut && !bind->isInOut )
2412+ ExtBind* extBind = new ExtBind ( NJS_EXTBIND_LOB );
2413+ if ( extBind )
24172414 {
2418- // Case for BIND_IN
2419- size = *bind->len ;
2420- }
2421- else if ( bind->isInOut )
2422- {
2423- // Case for BIND_INOUT
2424- size = ( bind->maxSize >= *( bind->len ) ) ? bind->maxSize : *( bind->len );
2425- }
2426- else if ( bind->isOut && !bind->isInOut )
2427- {
2428- // Case for BIND_OUT
2429- size = bind->maxSize ;
2430- }
2431-
2432- if ( size > NJS_THRESHOLD_SIZE_PLSQL_STRING_ARG )
2433- {
2434- ExtBind* extBind = new ExtBind ( NJS_EXTBIND_LOB );
2435- if ( !extBind )
2436- {
2437- executeBaton->error = NJSMessages::getErrorMsg
2438- ( errInsufficientMemory );
2439- goto exitConvertStringOrBuffer2LOB;
2440- }
24412415 extBind->fields .extLob .maxSize = bind->maxSize ;
24422416
24432417 // Convert the input data into Temp LOB for IN and INOUT binds
@@ -2462,9 +2436,13 @@ void Connection::ConvertStringOrBuffer2LOB ( eBaton* executeBaton,
24622436
24632437 // Change the bind->type to LOB to handle more than 32k data
24642438 bind->type = ( bind->type == DpiVarChar ) ? DpiClob : DpiBlob;
2439+
2440+ }
2441+ else
2442+ {
2443+ executeBaton->error = NJSMessages::getErrorMsg
2444+ ( errInsufficientMemory );
24652445 }
2466- exitConvertStringOrBuffer2LOB:
2467- ;
24682446}
24692447
24702448
@@ -2517,98 +2495,104 @@ void Connection::PrepareLOBsForBind ( eBaton* executeBaton, unsigned int index )
25172495 */
25182496void Connection::PrepareAndBind (eBaton* executeBaton)
25192497{
2520- executeBaton->dpistmt = executeBaton->dpiconn ->getStmt (executeBaton->sql );
2521- executeBaton->st = executeBaton->dpistmt ->stmtType ();
2498+ executeBaton->dpistmt = executeBaton->dpiconn ->
2499+ getStmt (executeBaton->sql );
2500+ executeBaton->st = executeBaton->dpistmt ->stmtType ();
25222501 executeBaton->stmtIsReturning = executeBaton->dpistmt ->isReturning ();
2523- ExtBind *extBind = NULL ;
2502+ ExtBind *extBind = NULL ;
25242503
25252504 if (!executeBaton->binds .empty ())
25262505 {
2527- if (!executeBaton->binds [0 ]->key .empty ())
2506+ for (unsigned int index = 0 ;index < executeBaton->binds .size ();
2507+ index++)
25282508 {
2529- for (unsigned int index = 0 ;index < executeBaton->binds .size ();
2530- index++)
2509+ if ( executeBaton->binds [index]->isOut &&
2510+ executeBaton->stmtIsReturning &&
2511+ executeBaton->binds [index]->type == dpi::DpiRSet )
25312512 {
2532- if ( executeBaton->binds [index]->isOut &&
2533- executeBaton->stmtIsReturning &&
2534- executeBaton->binds [index]->type == dpi::DpiRSet )
2535- {
2536- executeBaton->error = NJSMessages::getErrorMsg (
2537- errInvalidResultSet ) ;
2538- goto exitPrepareAndBind;
2539- }
2513+ executeBaton->error = NJSMessages::getErrorMsg (
2514+ errInvalidResultSet ) ;
2515+ goto exitPrepareAndBind;
2516+ }
25402517
2541- // Process bind enhancements CLOB/BLOB As String/Buffer for PL/SQL
2542- if ( ( executeBaton->st == DpiStmtBegin ||
2543- executeBaton->st == DpiStmtDeclare ||
2544- executeBaton->st == DpiStmtCall ) &&
2545- ( executeBaton->binds [index]->type == DpiVarChar ||
2546- executeBaton->binds [index]->type == DpiRaw ) )
2518+ // Process bind enhancements CLOB/BLOB As String/Buffer for PL/SQL
2519+ /* Interested only in PL/SQL procedure calls */
2520+ if ( ( executeBaton->st == DpiStmtBegin ||
2521+ executeBaton->st == DpiStmtDeclare ||
2522+ executeBaton->st == DpiStmtCall ))
2523+ {
2524+ /* Interested only in STRING or RAW data type */
2525+ if ( executeBaton->binds [index]->type == DpiVarChar ||
2526+ executeBaton->binds [index]->type == DpiRaw )
25472527 {
2548- ConvertStringOrBuffer2LOB ( executeBaton, index );
2528+ if ( IsValue2TempLob ( executeBaton, index ) )
2529+ {
2530+ ConvertStringOrBuffer2LOB ( executeBaton, index ) ;
2531+ }
25492532 }
2533+ }
2534+
2535+ // process LOB object for IN and INOUT bind
2536+ if ( ( executeBaton->binds [index]->isInOut ||
2537+ !executeBaton->binds [index]->isOut ) &&
2538+ ( *(executeBaton->binds [index]->ind ) != -1 ) &&
2539+ ( executeBaton->binds [index]->type == DpiClob ||
2540+ executeBaton->binds [index]->type == DpiBlob ) )
2541+ {
2542+ PrepareLOBsForBind ( executeBaton, index );
2543+ }
2544+
2545+ // Allocate for OUT Binds
2546+ // For DML Returning, allocation happens through callback.
2547+ // binds->value is a pointer to a pointer in case of LOBs
2548+ if ( executeBaton->binds [index]->isOut &&
2549+ !executeBaton->stmtIsReturning &&
2550+ !executeBaton->binds [index]->value )
2551+ {
2552+ Connection::cbDynBufferAllocate ( executeBaton, false , 1 , index );
25502553
25512554 if ( !executeBaton->error .empty () )
25522555 {
25532556 goto exitPrepareAndBind;
25542557 }
2558+ }
25552559
2556- // process LOB object for IN and INOUT bind
2557- if ( ( executeBaton->binds [index]->isInOut ||
2558- !executeBaton->binds [index]->isOut ) &&
2559- ( *(executeBaton->binds [index]->ind ) != -1 ) &&
2560- ( executeBaton->binds [index]->type == DpiClob ||
2561- executeBaton->binds [index]->type == DpiBlob ) )
2562- {
2563- PrepareLOBsForBind ( executeBaton, index );
2564- }
2565-
2566- // Allocate for OUT Binds
2567- // For DML Returning, allocation happens through callback.
2568- // binds->value is a pointer to a pointer in case of LOBs
2569- if ( executeBaton->binds [index]->isOut &&
2570- !executeBaton->stmtIsReturning &&
2571- !executeBaton->binds [index]->value )
2572- {
2573- Connection::cbDynBufferAllocate ( executeBaton,
2574- false , 1 , index );
2575- }
2560+ // Convert v8::Date to Oracle DB Type for IN and IN/OUT binds
2561+ if ( executeBaton->binds [index]->type == DpiTimestampLTZ &&
2562+ ( executeBaton->binds [index]->isInOut || // INOUT binds
2563+ !executeBaton->binds [index]->isOut ) ) // NOT OUT && NOT INOUT
2564+ {
2565+ Connection::UpdateDateValue ( executeBaton,
2566+ executeBaton->binds [index], 1 ) ;
2567+ }
25762568
2577- // Convert v8::Date to Oracle DB Type for IN and IN/OUT binds
2578- if ( executeBaton->binds [index]->type == DpiTimestampLTZ &&
2579- ( executeBaton->binds [index]->isInOut || // INOUT binds
2580- !executeBaton->binds [index]->isOut ) ) // NOT OUT && NOT INOUT
2581- {
2582- Connection::UpdateDateValue ( executeBaton,
2583- executeBaton->binds [index], 1 ) ;
2584- }
2569+ if ( executeBaton->stmtIsReturning && executeBaton->binds [index]->isOut )
2570+ {
2571+ extBind = new ExtBind ( NJS_EXTBIND_DMLRETCB ) ;
25852572
2586- if ( executeBaton->stmtIsReturning &&
2587- executeBaton->binds [index]->isOut )
2573+ DpiBindCallbackCtx *ctx = extBind->fields .extDMLReturnCbCtx .ctx =
2574+ (DpiBindCallbackCtx *) malloc ( sizeof ( DpiBindCallbackCtx ) );
2575+ if ( !ctx )
25882576 {
2589- extBind = new ExtBind ( NJS_EXTBIND_DMLRETCB ) ;
2590-
2591- DpiBindCallbackCtx *ctx = extBind->fields .extDMLReturnCbCtx .ctx =
2592- (DpiBindCallbackCtx *) malloc ( sizeof ( DpiBindCallbackCtx ) );
2593- if ( !ctx )
2594- {
2595- executeBaton->error = NJSMessages::getErrorMsg (
2577+ executeBaton->error = NJSMessages::getErrorMsg (
25962578 errInsufficientMemory );
2597- goto exitPrepareAndBind;
2598- }
2579+ goto exitPrepareAndBind;
2580+ }
25992581
2600- ctx->callbackfn = Connection::cbDynBufferGet;
2582+ ctx->callbackfn = Connection::cbDynBufferGet;
26012583 /* App specific callback */
2602- ctx->data = (void *)executeBaton;
2584+ ctx->data = (void *)executeBaton;
26032585 /* Data for App specific callback */
2604- ctx->bndpos = index; /* for callback, bind position zero based */
2605- ctx->nrows = 0 ; /* # of rows - will be filled in later */
2606- ctx->iter = 0 ; /* # iteration - will be filled in later */
2607- ctx->dpistmt = executeBaton->dpistmt ; /* DPI Statement object */
2586+ ctx->bndpos = index; /* for callback, bind position zero based */
2587+ ctx->nrows = 0 ; /* # of rows - will be filled in later */
2588+ ctx->iter = 0 ; /* # iteration - will be filled in later */
2589+ ctx->dpistmt = executeBaton->dpistmt ; /* DPI Statement object */
26082590
2609- executeBaton->extBinds [index] = extBind;
2610- }
2591+ executeBaton->extBinds [index] = extBind;
2592+ }
26112593
2594+ if ( !executeBaton->binds [index]->key .empty () )
2595+ {
26122596 // Bind by name
26132597 executeBaton->dpistmt ->bind (
26142598 (const unsigned char *)executeBaton->binds [index]->key .c_str (),
@@ -2630,83 +2614,8 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
26302614 executeBaton->binds [index]->isOut ) ?
26312615 extBind->fields .extDMLReturnCbCtx .ctx : NULL );
26322616 }
2633- }
2634- else
2635- {
2636- for (unsigned int index = 0 ;index < executeBaton->binds .size ();
2637- index++)
2617+ else
26382618 {
2639- // Process bind enhancements CLOB/BLOB As String/Buffer for PL/SQL
2640- if ( ( executeBaton->st == DpiStmtBegin ||
2641- executeBaton->st == DpiStmtDeclare ||
2642- executeBaton->st == DpiStmtCall ) &&
2643- ( executeBaton->binds [index]->type == DpiVarChar ||
2644- executeBaton->binds [index]->type == DpiRaw ) )
2645- {
2646- ConvertStringOrBuffer2LOB ( executeBaton, index );
2647- }
2648-
2649- if ( !executeBaton->error .empty () )
2650- {
2651- goto exitPrepareAndBind;
2652- }
2653-
2654- // process LOB object for IN and INOUT bind
2655- if ( ( executeBaton->binds [index]->isInOut ||
2656- !executeBaton->binds [index]->isOut ) &&
2657- ( *(executeBaton->binds [index]->ind ) != -1 ) &&
2658- ( executeBaton->binds [index]->type == DpiClob ||
2659- executeBaton->binds [index]->type == DpiBlob ) )
2660- {
2661- PrepareLOBsForBind ( executeBaton, index );
2662- }
2663-
2664- // Allocate for OUT Binds
2665- // For DML Returning, allocation happens through callback
2666- if ( executeBaton->binds [index]->isOut &&
2667- !executeBaton->stmtIsReturning &&
2668- !executeBaton->binds [index]->value )
2669- {
2670- Connection::cbDynBufferAllocate ( executeBaton,
2671- false , 1 , index );
2672- }
2673-
2674- // Convert v8::Date to Oracle DB Type for IN and IN/OUT binds
2675- if ( executeBaton->binds [index]->type == DpiTimestampLTZ &&
2676- // InOut bind
2677- (executeBaton->binds [index]->isInOut ||
2678- // In bind
2679- (!executeBaton->binds [index]->isOut &&
2680- !executeBaton->binds [index]->isInOut )))
2681- {
2682- Connection::UpdateDateValue ( executeBaton,
2683- executeBaton->binds [index], 1 ) ;
2684- }
2685-
2686- if ( executeBaton->stmtIsReturning &&
2687- executeBaton->binds [index]->isOut )
2688- {
2689- extBind = new ExtBind ( NJS_EXTBIND_DMLRETCB );
2690- DpiBindCallbackCtx *ctx = extBind->fields .extDMLReturnCbCtx .ctx =
2691- (DpiBindCallbackCtx *) malloc ( sizeof ( DpiBindCallbackCtx ) );
2692-
2693- if ( !ctx )
2694- {
2695- executeBaton->error = NJSMessages::getErrorMsg (
2696- errInsufficientMemory );
2697- goto exitPrepareAndBind;
2698- }
2699- ctx->callbackfn = Connection::cbDynBufferGet;
2700- /* App specific callback */
2701- ctx->data = (void *)executeBaton;
2702- /* Data for App specific callback */
2703- ctx->bndpos = index; /* for callback, bind position zero based */
2704- ctx->nrows = 0 ; /* # of rows - will be filled in later */
2705- ctx->iter = 0 ; /* # iteration - will be filled in later */
2706- ctx->dpistmt = executeBaton->dpistmt ; /* DPI Statement object */
2707- executeBaton->extBinds [index] = extBind;
2708- }
2709-
27102619 // Bind by position
27112620 executeBaton->dpistmt ->bind (
27122621 index+1 ,executeBaton->binds [index]->type ,
0 commit comments