54
54
#include " njsIntLob.h"
55
55
#include < stdlib.h>
56
56
#include < limits>
57
+
57
58
using namespace std ;
58
59
59
60
// persistent Connection class handle
@@ -68,7 +69,11 @@ Nan::Persistent<FunctionTemplate> Connection::connectionTemplate_s;
68
69
69
70
// Size of block allocated each time when callback is called for
70
71
// for fetch-CLOB-as-STRING. This constant is used only CLOB-as-STRING case
71
- #define NJS_ITER_SIZE 1048576
72
+ #if OCI_MAJOR_VERSION >= 12
73
+ #define NJS_ITER_SIZE 524287 /* Use (512KB - 1) with 12c Clients */
74
+ #else
75
+ #define NJS_ITER_SIZE 65535 /* Use (64KB - 1) with 11g Clients */
76
+ #endif
72
77
73
78
// Max number of bytes allowed for PLSQL STRING/BUFFER arguments
74
79
#define NJS_THRESHOLD_SIZE_PLSQL_STRING_ARG 32767
@@ -2560,6 +2565,13 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
2560
2565
2561
2566
DpiBindCallbackCtx *ctx = extBind->fields .extDMLReturnCbCtx .ctx =
2562
2567
(DpiBindCallbackCtx *) malloc ( sizeof ( DpiBindCallbackCtx ) );
2568
+ if ( !ctx )
2569
+ {
2570
+ executeBaton->error = NJSMessages::getErrorMsg (
2571
+ errInsufficientMemory );
2572
+ goto exitPrepareAndBind;
2573
+ }
2574
+
2563
2575
ctx->callbackfn = Connection::cbDynBufferGet;
2564
2576
/* App specific callback */
2565
2577
ctx->data = (void *)executeBaton;
@@ -2653,6 +2665,12 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
2653
2665
DpiBindCallbackCtx *ctx = extBind->fields .extDMLReturnCbCtx .ctx =
2654
2666
(DpiBindCallbackCtx *) malloc ( sizeof ( DpiBindCallbackCtx ) );
2655
2667
2668
+ if ( !ctx )
2669
+ {
2670
+ executeBaton->error = NJSMessages::getErrorMsg (
2671
+ errInsufficientMemory );
2672
+ goto exitPrepareAndBind;
2673
+ }
2656
2674
ctx->callbackfn = Connection::cbDynBufferGet;
2657
2675
/* App specific callback */
2658
2676
ctx->data = (void *)executeBaton;
@@ -3337,6 +3355,25 @@ void Connection::DoFetch (eBaton* executeBaton)
3337
3355
NJSErrorType errNum = errSuccess;
3338
3356
executeBaton->dpistmt ->fetch ( executeBaton->maxRows );
3339
3357
executeBaton->rowsFetched = executeBaton->dpistmt ->rowsFetched ();
3358
+
3359
+ for ( unsigned int col = 0 ; col < executeBaton->numCols ; col ++ )
3360
+ {
3361
+ Define *define = &(executeBaton->defines [col] );
3362
+ ExtDefine *extDefine = executeBaton->extDefines [col];
3363
+
3364
+ if ( extDefine && extDefine -> extDefType == NJS_EXTDEFINE_CLOBASSTR )
3365
+ {
3366
+ /* In case of fetch-clob-as-string, the last read operation has partial
3367
+ * size read, and consolidated len is maintained in extDefine, add both
3368
+ * and set it back to define->len[row] it can be used later
3369
+ */
3370
+ for ( unsigned int row = 0 ; row < executeBaton->rowsFetched ; row ++ )
3371
+ {
3372
+ define->len [row] += extDefine->fields .extClobAsStr .cLen ;
3373
+ }
3374
+ }
3375
+ }
3376
+
3340
3377
errNum = Connection::Descr2Double ( executeBaton->defines ,
3341
3378
executeBaton->numCols ,
3342
3379
executeBaton->rowsFetched ,
@@ -4116,7 +4153,7 @@ Local<Value> Connection::GetValueCommon ( eBaton *executeBaton,
4116
4153
switch (type)
4117
4154
{
4118
4155
case (dpi::DpiVarChar) :
4119
- value = Nan::New<v8::String>((char *)val, len).ToLocalChecked ();
4156
+ value = Nan::New<v8::String>((char *)val, len).ToLocalChecked ();
4120
4157
break ;
4121
4158
case (dpi::DpiInteger) :
4122
4159
value = Nan::New<v8::Integer>(*(int *)val);
@@ -5548,28 +5585,30 @@ int Connection::cbDynDefine ( void *octxp, unsigned long definePos,
5548
5585
{
5549
5586
eBaton *executeBaton = (eBaton *) octxp ;
5550
5587
Define *define = &(executeBaton->defines [definePos]);
5551
- unsigned long maxLen = 0 ;
5588
+ ExtDefine *extDefine = executeBaton->extDefines [definePos];
5589
+ unsigned long maxLen = NJS_ITER_SIZE ;
5552
5590
char **buf = (char **)define->buf ;
5553
5591
char *tmp = NULL ; // to presever ptr for realloc
5554
5592
int ret = 0 ;
5555
5593
5556
5594
if ( *prevIter != iter )
5557
5595
{
5558
- // For next row, start from minimum buffer
5559
- maxLen = NJS_ITER_SIZE ;
5560
5596
*prevIter = iter;
5597
+ extDefine->fields .extClobAsStr .cLen = 0 ;
5561
5598
}
5562
5599
else
5563
5600
{
5564
- // More data for same row, try with next incremental size
5565
- maxLen = ( ( ( unsigned long ) (**alenpp ) ) + NJS_ITER_SIZE ) ;
5601
+ // maintain incremental size of clob
5602
+ extDefine-> fields . extClobAsStr . cLen += NJS_ITER_SIZE ;
5566
5603
}
5567
5604
5568
5605
tmp = buf[iter]; // preserve the current memory address
5569
5606
5570
5607
// allocate or reallocate buffer
5571
5608
buf[iter] = (char *) ( ( !buf[iter] ) ?
5572
- malloc ( maxLen ) : realloc ( buf[iter], maxLen ) ) ;
5609
+ malloc ( maxLen ) :
5610
+ realloc ( buf[iter],
5611
+ maxLen + extDefine->fields .extClobAsStr .cLen ) ) ;
5573
5612
if ( !buf[iter] )
5574
5613
{
5575
5614
// If realloc fails, the IN parameter requires to be freed and untouched
@@ -5582,7 +5621,7 @@ int Connection::cbDynDefine ( void *octxp, unsigned long definePos,
5582
5621
define->len [iter] = maxLen;
5583
5622
define->ind [iter] = 0 ; // default value for indicator
5584
5623
5585
- *bufpp = (void *) buf[iter]; // memory for this iter
5624
+ *bufpp = (void *) (& buf[iter][extDefine-> fields . extClobAsStr . cLen ]);
5586
5625
*alenpp = (unsigned long *) &(define->len [iter]) ; // size for this iter
5587
5626
*indpp = (void *) &(define->ind [iter]); // indicator
5588
5627
}
0 commit comments