@@ -834,14 +834,13 @@ void Connection::GetBindUnit (Local<Value> val, Bind* bind, bool array,
834
834
case NJS_BIND_IN :
835
835
bind->isOut = false ;
836
836
bind->isInOut = false ;
837
- Connection::GetInBindParams (element, bind, executeBaton, NJS_BIND_IN );
837
+ Connection::GetInBindParams (element, bind, executeBaton );
838
838
if (!executeBaton->error .empty ()) goto exitGetBindUnit;
839
839
break ;
840
840
case NJS_BIND_INOUT :
841
841
bind->isOut = true ;
842
842
bind->isInOut = true ;
843
- Connection::GetInBindParams (element, bind, executeBaton,
844
- NJS_BIND_INOUT);
843
+ Connection::GetInBindParams (element, bind, executeBaton );
845
844
if (!executeBaton->error .empty ()) goto exitGetBindUnit;
846
845
break ;
847
846
case NJS_BIND_OUT :
@@ -866,7 +865,7 @@ void Connection::GetBindUnit (Local<Value> val, Bind* bind, bool array,
866
865
else
867
866
{
868
867
bind->isOut = false ;
869
- Connection::GetInBindParams (val, bind, executeBaton, NJS_BIND_IN );
868
+ Connection::GetInBindParams (val, bind, executeBaton );
870
869
if (!executeBaton->error .empty ()) goto exitGetBindUnit;
871
870
}
872
871
exitGetBindUnit:
@@ -957,17 +956,17 @@ void Connection::GetOutBindParams (unsigned short dataType, Bind* bind,
957
956
allocate for one unit.
958
957
*/
959
958
void Connection::GetInBindParams (Local<Value> v8val, Bind* bind,
960
- eBaton* executeBaton, BindType type )
959
+ eBaton* executeBaton )
961
960
{
962
961
Nan::HandleScope scope;
963
962
964
963
if (v8val->IsArray () )
965
964
{
966
- GetInBindParamsArray (Local<Array>::Cast (v8val), bind, executeBaton, type );
965
+ GetInBindParamsArray (Local<Array>::Cast (v8val), bind, executeBaton );
967
966
}
968
967
else
969
968
{
970
- GetInBindParamsScalar (v8val, bind, executeBaton, type );
969
+ GetInBindParamsScalar (v8val, bind, executeBaton );
971
970
}
972
971
}
973
972
@@ -984,20 +983,54 @@ void Connection::GetInBindParams(Local<Value> v8val, Bind* bind,
984
983
allocate for one unit.
985
984
*/
986
985
void Connection::GetInBindParamsScalar (Local<Value> v8val, Bind* bind,
987
- eBaton* executeBaton, BindType type )
986
+ eBaton* executeBaton)
988
987
{
989
988
Nan::HandleScope scope;
990
- ValueType dataType = NJS_VALUETYPE_INVALID;
989
+ ValueType valType = NJS_VALUETYPE_INVALID;
990
+ boolean v8valNULL ; /* whether given v8 value is NULL/Undefined */
991
991
992
992
/* Allocate for scalar indicator & length */
993
993
bind->ind = (short *)malloc ( sizeof ( short ) );
994
994
bind->len = (DPI_BUFLEN_TYPE *)malloc ( sizeof ( DPI_BUFLEN_TYPE ) );
995
995
996
996
*(bind->ind ) = 0 ;
997
997
998
- dataType = Connection::GetValueType ( v8val );
998
+ valType = Connection::GetValueType ( v8val );
999
+ v8valNULL = ( valType == NJS_VALUETYPE_NULL ) ? true : false ;
999
1000
1000
- switch ( dataType )
1001
+ /*
1002
+ * In case of INOUT Bind, if given value is NULL
1003
+ * make use of specified OUT bind type
1004
+ */
1005
+ if ( v8valNULL && bind->isInOut )
1006
+ {
1007
+ switch ( bind->type )
1008
+ {
1009
+ case NJS_DATATYPE_STR:
1010
+ valType = NJS_VALUETYPE_STRING;
1011
+ break ;
1012
+
1013
+ case NJS_DATATYPE_NUM:
1014
+ valType = NJS_VALUETYPE_NUMBER;
1015
+ break ;
1016
+
1017
+ case NJS_DATATYPE_DATE:
1018
+ valType = NJS_VALUETYPE_DATE;
1019
+ break ;
1020
+
1021
+ case NJS_DATATYPE_BUFFER:
1022
+ valType = NJS_VALUETYPE_OBJECT; /* DB RAW Type, v8 Buffer */
1023
+ break ;
1024
+
1025
+ // The following types are NOT supported as IN BIND (for INOUT) ignore
1026
+ case NJS_DATATYPE_CURSOR:
1027
+ case NJS_DATATYPE_CLOB:
1028
+ case NJS_DATATYPE_BLOB:
1029
+ break ;
1030
+ }
1031
+ }
1032
+
1033
+ switch ( valType )
1001
1034
{
1002
1035
case NJS_VALUETYPE_NULL:
1003
1036
bind->value = NULL ;
@@ -1014,10 +1047,16 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1014
1047
goto exitGetInBindParamsScalar;
1015
1048
}
1016
1049
1017
- v8::String::Utf8Value str (v8val->ToString ());
1050
+ /*
1051
+ * Use empty string in case of IN value is NULL, but overriden for
1052
+ * INOUT binds
1053
+ */
1054
+ v8::String::Utf8Value str ( v8valNULL ?
1055
+ Nan::New<v8::String> ( " " , 0 ).ToLocalChecked () :
1056
+ v8val->ToString ());
1018
1057
1019
1058
bind->type = dpi::DpiVarChar;
1020
- if (type == NJS_BIND_INOUT )
1059
+ if ( bind-> isInOut )
1021
1060
{
1022
1061
*(bind->len ) = str.length ();
1023
1062
}
@@ -1053,7 +1092,7 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1053
1092
bind->type = dpi::DpiInteger;
1054
1093
bind->maxSize = *(bind->len ) = sizeof (int );
1055
1094
bind->value = (int *)malloc (*(bind->len ));
1056
- *(int *)(bind->value ) = v8val->ToInt32 ()->Value ();
1095
+ *(int *)(bind->value ) = v8valNULL ? 0 : v8val->ToInt32 ()->Value ();
1057
1096
break ;
1058
1097
1059
1098
case NJS_VALUETYPE_UINTEGER:
@@ -1066,7 +1105,8 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1066
1105
bind->type = dpi::DpiUnsignedInteger;
1067
1106
bind->maxSize = *(bind->len ) = sizeof (unsigned int );
1068
1107
bind->value = (unsigned int *)malloc (*(bind->len ));
1069
- *(unsigned int *)(bind->value ) = v8val->ToUint32 ()->Value ();
1108
+ *(unsigned int *)(bind->value ) = v8valNULL ? 0 :
1109
+ v8val->ToUint32 ()->Value ();
1070
1110
break ;
1071
1111
1072
1112
case NJS_VALUETYPE_NUMBER:
@@ -1079,7 +1119,7 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1079
1119
bind->type = dpi::DpiDouble;
1080
1120
bind->maxSize = *(bind->len ) = sizeof (double );
1081
1121
bind->value = (double *)malloc (*(bind->len ));
1082
- *(double *)(bind->value ) = v8val->NumberValue ();
1122
+ *(double *)(bind->value ) = v8valNULL ? 0 : v8val->NumberValue ();
1083
1123
break ;
1084
1124
1085
1125
case NJS_VALUETYPE_DATE:
@@ -1104,11 +1144,23 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1104
1144
case NJS_VALUETYPE_OBJECT:
1105
1145
{
1106
1146
Local<Object> obj = v8val->ToObject ();
1107
- if (Buffer::HasInstance (obj))
1147
+
1148
+ if ( v8valNULL && bind->isInOut )
1149
+ {
1150
+ /*
1151
+ * In case of RAW/Buffer type and INOUT Bind, if IN value is NULL,
1152
+ * allocate based on OUT type, maxSize
1153
+ */
1154
+ bind->type = dpi::DpiRaw;
1155
+ *( bind->len ) = ( DPI_BUFLEN_TYPE ) (( bind->isInOut ) ?
1156
+ bind->maxSize : 0 );
1157
+ bind->value = ( char *) malloc ( *(bind -> len ) );
1158
+ }
1159
+ else if (Buffer::HasInstance (obj))
1108
1160
{
1109
1161
size_t bufLen = Buffer::Length (obj);
1110
1162
bind->type = dpi::DpiRaw;
1111
- if (type == NJS_BIND_INOUT )
1163
+ if ( bind-> isInOut )
1112
1164
{
1113
1165
*(bind->len ) = (DPI_BUFLEN_TYPE) bufLen;
1114
1166
}
@@ -1160,7 +1212,7 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1160
1212
allocate for one unit.
1161
1213
*/
1162
1214
void Connection::GetInBindParamsArray (Local<Array> va8vals, Bind *bind,
1163
- eBaton *executeBaton, BindType type )
1215
+ eBaton *executeBaton )
1164
1216
{
1165
1217
Nan::HandleScope scope;
1166
1218
size_t arrayElementSize = 0 ; // actual array element size
@@ -3906,8 +3958,9 @@ void Connection::v8Date2OraDate(v8::Local<v8::Value> val, Bind *bind)
3906
3958
Local<Date> date = val.As <Date>(); // Expects to be of v8::Date type
3907
3959
3908
3960
// Get the number of seconds from 1970-1-1 0:0:0
3909
- *(long double *)(bind->extvalue ) = date->NumberValue ();
3910
-
3961
+ // In case given value is NULL/Undefined, set it to 0
3962
+ *(long double *)(bind->extvalue ) = (val->IsNull () || val->IsUndefined ()) ?
3963
+ 0 : date->NumberValue ();
3911
3964
}
3912
3965
3913
3966
/* **************************************************************************/
@@ -3979,45 +4032,59 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
3979
4032
3980
4033
Connection::AllocateBindArray ( bind->type , bind, executeBaton,
3981
4034
&arrayElementSize );
3982
- return ;
4035
+ goto exitcbDynBufferAllocate ;
3983
4036
}
3984
4037
3985
4038
3986
4039
if ( NJS_SIZE_T_OVERFLOW ( sizeof ( short ), nRows ) )
3987
4040
{
3988
4041
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
3989
- return ;
4042
+ goto exitcbDynBufferAllocate ;
3990
4043
}
3991
4044
else
3992
4045
{
3993
- bind->ind = (short *)malloc ( (size_t )nRows * sizeof ( short ) ) ;
3994
- if ( !bind->ind )
4046
+ if ( !bind->ind )
3995
4047
{
3996
- executeBaton->error = NJSMessages::getErrorMsg ( errInsufficientMemory );
3997
- return ;
4048
+ bind->ind = (short *)malloc ( (size_t )nRows * sizeof ( short ) ) ;
4049
+ if ( !bind->ind )
4050
+ {
4051
+ executeBaton->error = NJSMessages::getErrorMsg (
4052
+ errInsufficientMemory );
4053
+ goto exitcbDynBufferAllocate;
4054
+ }
3998
4055
}
3999
4056
}
4000
4057
if ( dmlReturning )
4001
4058
{
4002
4059
if ( NJS_SIZE_T_OVERFLOW ( sizeof ( unsigned int ), nRows ) )
4003
4060
{
4004
4061
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4005
- return ;
4062
+ goto exitcbDynBufferAllocate ;
4006
4063
}
4007
4064
else
4008
4065
{
4009
4066
bind->len2 = ( unsigned int *)malloc ( nRows * sizeof ( unsigned int ) );
4010
4067
if ( !bind->len2 )
4011
4068
{
4012
- executeBaton->error = NJSMessages::getErrorMsg ( errInsufficientMemory );
4013
- return ;
4069
+ executeBaton->error = NJSMessages::getErrorMsg (
4070
+ errInsufficientMemory );
4071
+ goto exitcbDynBufferAllocate;
4014
4072
}
4015
4073
}
4016
4074
}
4017
4075
else
4018
4076
{
4019
- bind->len = (DPI_BUFLEN_TYPE *)malloc ( nRows *
4020
- sizeof ( DPI_BUFLEN_TYPE ) );
4077
+ if ( !bind->len )
4078
+ {
4079
+ bind->len = (DPI_BUFLEN_TYPE *)malloc ( nRows *
4080
+ sizeof ( DPI_BUFLEN_TYPE ) );
4081
+ if ( !bind->len )
4082
+ {
4083
+ executeBaton->error = NJSMessages::getErrorMsg (
4084
+ errInsufficientMemory ) ;
4085
+ goto exitcbDynBufferAllocate;
4086
+ }
4087
+ }
4021
4088
}
4022
4089
4023
4090
switch ( bind->type )
@@ -4028,7 +4095,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4028
4095
if ( NJS_SIZE_T_OVERFLOW ( (bind->maxSize + 1 ), nRows) )
4029
4096
{
4030
4097
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4031
- return ;
4098
+ goto exitcbDynBufferAllocate ;
4032
4099
}
4033
4100
else
4034
4101
{
@@ -4037,7 +4104,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4037
4104
{
4038
4105
executeBaton->error = NJSMessages::getErrorMsg (
4039
4106
errInsufficientMemory);
4040
- return ;
4107
+ goto exitcbDynBufferAllocate ;
4041
4108
}
4042
4109
}
4043
4110
@@ -4055,7 +4122,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4055
4122
if ( NJS_SIZE_T_OVERFLOW ( sizeof (int ), nRows) )
4056
4123
{
4057
4124
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4058
- return ;
4125
+ goto exitcbDynBufferAllocate ;
4059
4126
}
4060
4127
else
4061
4128
{
@@ -4064,7 +4131,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4064
4131
{
4065
4132
executeBaton->error = NJSMessages::getErrorMsg (
4066
4133
errInsufficientMemory);
4067
- return ;
4134
+ goto exitcbDynBufferAllocate ;
4068
4135
}
4069
4136
}
4070
4137
if ( !dmlReturning )
@@ -4077,7 +4144,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4077
4144
if ( NJS_SIZE_T_OVERFLOW ( sizeof ( unsigned int ), nRows) )
4078
4145
{
4079
4146
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4080
- return ;
4147
+ goto exitcbDynBufferAllocate ;
4081
4148
}
4082
4149
else
4083
4150
{
@@ -4086,7 +4153,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4086
4153
{
4087
4154
executeBaton->error = NJSMessages::getErrorMsg (
4088
4155
errInsufficientMemory);
4089
- return ;
4156
+ goto exitcbDynBufferAllocate ;
4090
4157
}
4091
4158
}
4092
4159
if ( !dmlReturning )
@@ -4099,7 +4166,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4099
4166
if ( NJS_SIZE_T_OVERFLOW ( sizeof ( double ), nRows) )
4100
4167
{
4101
4168
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4102
- return ;
4169
+ goto exitcbDynBufferAllocate ;
4103
4170
}
4104
4171
else
4105
4172
{
@@ -4108,7 +4175,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4108
4175
{
4109
4176
executeBaton->error = NJSMessages::getErrorMsg (
4110
4177
errInsufficientMemory);
4111
- return ;
4178
+ goto exitcbDynBufferAllocate ;
4112
4179
}
4113
4180
}
4114
4181
if ( !dmlReturning )
@@ -4131,7 +4198,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4131
4198
if ( NJS_SIZE_T_OVERFLOW ( sizeof ( Descriptor * ), nRows) )
4132
4199
{
4133
4200
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4134
- return ;
4201
+ goto exitcbDynBufferAllocate ;
4135
4202
}
4136
4203
else
4137
4204
{
@@ -4140,7 +4207,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4140
4207
{
4141
4208
executeBaton->error = NJSMessages::getErrorMsg (
4142
4209
errInsufficientMemory);
4143
- return ;
4210
+ goto exitcbDynBufferAllocate ;
4144
4211
}
4145
4212
}
4146
4213
// and allocate the underlying descriptor(s)
@@ -4161,7 +4228,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4161
4228
if ( NJS_SIZE_T_OVERFLOW ( sizeof ( long double ), nRows) )
4162
4229
{
4163
4230
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4164
- return ;
4231
+ goto exitcbDynBufferAllocate ;
4165
4232
}
4166
4233
else
4167
4234
{
@@ -4171,7 +4238,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4171
4238
{
4172
4239
executeBaton->error = NJSMessages::getErrorMsg (
4173
4240
errInsufficientMemory);
4174
- return ;
4241
+ goto exitcbDynBufferAllocate ;
4175
4242
}
4176
4243
}
4177
4244
// needed to post-process DML RETURNING of TimestampLTZ
@@ -4194,7 +4261,7 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4194
4261
if ( NJS_SIZE_T_OVERFLOW ( bind->maxSize , nRows ) )
4195
4262
{
4196
4263
executeBaton->error = NJSMessages::getErrorMsg ( errResultsTooLarge );
4197
- return ;
4264
+ goto exitcbDynBufferAllocate ;
4198
4265
}
4199
4266
else
4200
4267
{
@@ -4203,6 +4270,9 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
4203
4270
}
4204
4271
break ;
4205
4272
}
4273
+
4274
+ exitcbDynBufferAllocate:
4275
+ ;
4206
4276
}
4207
4277
4208
4278
/* ***************************************************************************/
0 commit comments