@@ -75,9 +75,6 @@ Nan::Persistent<FunctionTemplate> Connection::connectionTemplate_s;
75
75
#define NJS_ITER_SIZE 65535 /* Use (64KB - 1) with 11g Clients */
76
76
#endif
77
77
78
- // Max number of bytes allowed for PLSQL STRING/BUFFER arguments
79
- #define NJS_THRESHOLD_SIZE_PLSQL_STRING_ARG 32767
80
-
81
78
// number of rows prefetched by non-ResultSet queries
82
79
#define NJS_PREFETCH_NON_RESULTSET 2
83
80
@@ -1088,6 +1085,7 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1088
1085
{
1089
1086
case NJS_VALUETYPE_NULL:
1090
1087
bind->value = NULL ;
1088
+ *(bind->len ) = 0 ; /* NULL value provided, no buffer used */
1091
1089
bind->type = dpi::DpiVarChar;
1092
1090
break ;
1093
1091
@@ -2403,41 +2401,17 @@ void Connection::Descr2StringOrBuffer ( eBaton* executeBaton )
2403
2401
* index - Index of the Bind vector
2404
2402
*
2405
2403
* 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
2408
2405
*
2409
2406
*/
2410
2407
void Connection::ConvertStringOrBuffer2LOB ( eBaton* executeBaton,
2411
2408
unsigned int index )
2412
2409
{
2413
2410
Bind *bind = executeBaton->binds [index ];
2414
- DPI_SZ_TYPE size = 0 ;
2415
2411
2416
- if ( !bind->isOut && !bind->isInOut )
2412
+ ExtBind* extBind = new ExtBind ( NJS_EXTBIND_LOB );
2413
+ if ( extBind )
2417
2414
{
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
- }
2441
2415
extBind->fields .extLob .maxSize = bind->maxSize ;
2442
2416
2443
2417
// Convert the input data into Temp LOB for IN and INOUT binds
@@ -2462,9 +2436,13 @@ void Connection::ConvertStringOrBuffer2LOB ( eBaton* executeBaton,
2462
2436
2463
2437
// Change the bind->type to LOB to handle more than 32k data
2464
2438
bind->type = ( bind->type == DpiVarChar ) ? DpiClob : DpiBlob;
2439
+
2440
+ }
2441
+ else
2442
+ {
2443
+ executeBaton->error = NJSMessages::getErrorMsg
2444
+ ( errInsufficientMemory );
2465
2445
}
2466
- exitConvertStringOrBuffer2LOB:
2467
- ;
2468
2446
}
2469
2447
2470
2448
@@ -2517,98 +2495,104 @@ void Connection::PrepareLOBsForBind ( eBaton* executeBaton, unsigned int index )
2517
2495
*/
2518
2496
void Connection::PrepareAndBind (eBaton* executeBaton)
2519
2497
{
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 ();
2522
2501
executeBaton->stmtIsReturning = executeBaton->dpistmt ->isReturning ();
2523
- ExtBind *extBind = NULL ;
2502
+ ExtBind *extBind = NULL ;
2524
2503
2525
2504
if (!executeBaton->binds .empty ())
2526
2505
{
2527
- if (!executeBaton->binds [0 ]->key .empty ())
2506
+ for (unsigned int index = 0 ;index < executeBaton->binds .size ();
2507
+ index ++)
2528
2508
{
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 )
2531
2512
{
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
+ }
2540
2517
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 )
2547
2527
{
2548
- ConvertStringOrBuffer2LOB ( executeBaton, index );
2528
+ if ( IsValue2TempLob ( executeBaton, index ) )
2529
+ {
2530
+ ConvertStringOrBuffer2LOB ( executeBaton, index ) ;
2531
+ }
2549
2532
}
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 );
2550
2553
2551
2554
if ( !executeBaton->error .empty () )
2552
2555
{
2553
2556
goto exitPrepareAndBind;
2554
2557
}
2558
+ }
2555
2559
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
+ }
2576
2568
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 ) ;
2585
2572
2586
- if ( executeBaton->stmtIsReturning &&
2587
- executeBaton->binds [index ]->isOut )
2573
+ DpiBindCallbackCtx *ctx = extBind->fields .extDMLReturnCbCtx .ctx =
2574
+ (DpiBindCallbackCtx *) malloc ( sizeof ( DpiBindCallbackCtx ) );
2575
+ if ( !ctx )
2588
2576
{
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 (
2596
2578
errInsufficientMemory );
2597
- goto exitPrepareAndBind;
2598
- }
2579
+ goto exitPrepareAndBind;
2580
+ }
2599
2581
2600
- ctx->callbackfn = Connection::cbDynBufferGet;
2582
+ ctx->callbackfn = Connection::cbDynBufferGet;
2601
2583
/* App specific callback */
2602
- ctx->data = (void *)executeBaton;
2584
+ ctx->data = (void *)executeBaton;
2603
2585
/* 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 */
2608
2590
2609
- executeBaton->extBinds [index ] = extBind;
2610
- }
2591
+ executeBaton->extBinds [index ] = extBind;
2592
+ }
2611
2593
2594
+ if ( !executeBaton->binds [index ]->key .empty () )
2595
+ {
2612
2596
// Bind by name
2613
2597
executeBaton->dpistmt ->bind (
2614
2598
(const unsigned char *)executeBaton->binds [index ]->key .c_str (),
@@ -2630,83 +2614,8 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
2630
2614
executeBaton->binds [index ]->isOut ) ?
2631
2615
extBind->fields .extDMLReturnCbCtx .ctx : NULL );
2632
2616
}
2633
- }
2634
- else
2635
- {
2636
- for (unsigned int index = 0 ;index < executeBaton->binds .size ();
2637
- index ++)
2617
+ else
2638
2618
{
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
-
2710
2619
// Bind by position
2711
2620
executeBaton->dpistmt ->bind (
2712
2621
index +1 ,executeBaton->binds [index ]->type ,
0 commit comments