Skip to content

Commit 51c0b81

Browse files
committed
Fix regression when binding dates with alternate JavaScript frameworks
1 parent ee69019 commit 51c0b81

File tree

6 files changed

+48
-19
lines changed

6 files changed

+48
-19
lines changed

lib/connection.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const BaseDbObject = require('./dbObject.js');
2323
const EventEmitter = require('events');
2424
const QueryStream = require('./querystream.js');
2525
const nodbUtil = require('./util.js');
26+
const util = require('util');
2627

2728
// fetchRowsToReturn is used to materialize the rows for an execute call using
2829
// the resultSet returned from the C layer.
@@ -425,6 +426,10 @@ class Connection extends EventEmitter {
425426
return cls;
426427
}
427428

429+
_isDate(val) {
430+
return util.types.isDate(val);
431+
}
432+
428433
// To obtain a SodaDatabase object (high-level SODA object associated with
429434
// current connection)
430435
getSodaDatabase() {

src/njsBaton.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,9 @@ bool njsBaton_isBindValue(njsBaton *baton, napi_env env, napi_value value)
799799
return true;
800800

801801
// dates can be bound directly
802-
if (njsBaton_isDate(baton, env, value))
802+
if (!njsBaton_isDate(baton, env, value, &check))
803+
return false;
804+
if (check)
803805
return true;
804806

805807
// LOBs can be bound directly
@@ -823,17 +825,18 @@ bool njsBaton_isBindValue(njsBaton *baton, napi_env env, napi_value value)
823825

824826
//-----------------------------------------------------------------------------
825827
// njsBaton_isDate()
826-
// Returns a boolean indicating if the value refers to a date or not.
828+
// Returns a boolean indicating if the value refers to a date or not. This
829+
// can be replaced by napi_is_date() once it is available in all LTS releases.
827830
//-----------------------------------------------------------------------------
828-
bool njsBaton_isDate(njsBaton *baton, napi_env env, napi_value value)
831+
bool njsBaton_isDate(njsBaton *baton, napi_env env, napi_value value,
832+
bool *isDate)
829833
{
830-
napi_status status;
831-
bool check;
834+
napi_value isDateObj;
832835

833-
status = napi_instanceof(env, value, baton->jsDateConstructor, &check);
834-
if (status != napi_ok)
835-
return false;
836-
return check;
836+
NJS_CHECK_NAPI(env, napi_call_function(env, baton->jsConnection,
837+
baton->jsIsDateMethod, 1, &value, &isDateObj))
838+
NJS_CHECK_NAPI(env, napi_get_value_bool(env, isDateObj, isDate))
839+
return true;
837840
}
838841

839842

@@ -912,10 +915,21 @@ void njsBaton_reportError(njsBaton *baton, napi_env env)
912915
// njsBaton_setConstructors()
913916
// Sets the constructors on the baton.
914917
//-----------------------------------------------------------------------------
915-
bool njsBaton_setConstructors(njsBaton *baton, napi_env env)
918+
bool njsBaton_setConstructors(njsBaton *baton, napi_env env, bool canBind)
916919
{
917920
napi_value global;
918921

922+
// if binding is possible, get the connection (which is the calling object)
923+
// and acquire the method used for determining if a value is a date; this
924+
// is needed until such time as napi_is_date() is available for all LTS
925+
// releases
926+
if (canBind) {
927+
NJS_CHECK_NAPI(env, napi_get_reference_value(env, baton->jsCallingObj,
928+
&baton->jsConnection))
929+
NJS_CHECK_NAPI(env, napi_get_named_property(env, baton->jsConnection,
930+
"_isDate", &baton->jsIsDateMethod))
931+
}
932+
919933
// acquire the Date constructor
920934
NJS_CHECK_NAPI(env, napi_get_global(env, &global))
921935
NJS_CHECK_NAPI(env, napi_get_named_property(env, global, "Date",

src/njsConnection.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ static bool njsConnection_executePostAsync(njsBaton *baton, napi_env env,
592592
napi_value implicitResults;
593593

594594
// create constructors used for various types that might be returned
595-
if (!njsBaton_setConstructors(baton, env))
595+
if (!njsBaton_setConstructors(baton, env, true))
596596
return false;
597597

598598
// create result object
@@ -685,7 +685,7 @@ static bool njsConnection_executeProcessArgs(njsBaton *baton,
685685
(void**) &baton->fetchAsStringTypes,
686686
&baton->numFetchAsStringTypes))
687687
return false;
688-
if (!njsBaton_setConstructors(baton, env))
688+
if (!njsBaton_setConstructors(baton, env, true))
689689
return false;
690690

691691
// get SQL from first argument
@@ -880,7 +880,7 @@ static bool njsConnection_executeManyProcessArgs(njsBaton *baton,
880880
{
881881
// setup defaults and define constructors for use in various checks
882882
baton->autoCommit = baton->oracleDb->autoCommit;
883-
if (!njsBaton_setConstructors(baton, env))
883+
if (!njsBaton_setConstructors(baton, env, true))
884884
return false;
885885

886886
// get SQL from first argument
@@ -1069,7 +1069,9 @@ static bool njsConnection_getBindInfoFromValue(njsBaton *baton,
10691069
if (valueType == napi_object) {
10701070

10711071
// dates can be bound
1072-
if (njsBaton_isDate(baton, env, value)) {
1072+
if (!njsBaton_isDate(baton, env, value, &check))
1073+
return false;
1074+
if (check) {
10731075
*bindType = NJS_DATATYPE_DATE;
10741076
return true;
10751077
}

src/njsModule.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,13 @@ struct njsBaton {
479479
napi_ref jsCallback;
480480
napi_ref jsSubscription;
481481

482+
// values required to check if a value is a date; this is only used when
483+
// binding data in connection.execute() and connection.executeMany();
484+
// this can be replaced with calls to napi_is_date() when it is available
485+
// for all LTS releases
486+
napi_value jsConnection;
487+
napi_value jsIsDateMethod;
488+
482489
// constructors
483490
napi_value jsDateConstructor;
484491
napi_value jsLobConstructor;
@@ -795,13 +802,14 @@ bool njsBaton_getValueFromArg(njsBaton *baton, napi_env env, napi_value *args,
795802
int argIndex, const char *propertyName, napi_valuetype expectedType,
796803
napi_value *value, bool *found);
797804
bool njsBaton_isBindValue(njsBaton *baton, napi_env env, napi_value value);
798-
bool njsBaton_isDate(njsBaton *baton, napi_env env, napi_value value);
805+
bool njsBaton_isDate(njsBaton *baton, napi_env env, napi_value value,
806+
bool *isDate);
799807
bool njsBaton_queueWork(njsBaton *baton, napi_env env, const char *methodName,
800808
bool (*workCallback)(njsBaton*),
801809
bool (*afterWorkCallback)(njsBaton*, napi_env, napi_value*),
802810
unsigned int numCallbackArgs);
803811
void njsBaton_reportError(njsBaton *baton, napi_env env);
804-
bool njsBaton_setConstructors(njsBaton *baton, napi_env env);
812+
bool njsBaton_setConstructors(njsBaton *baton, napi_env env, bool canBind);
805813
bool njsBaton_setError(njsBaton *baton, int errNum, ...);
806814
bool njsBaton_setErrorDPI(njsBaton *baton);
807815

src/njsResultSet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ static bool njsResultSet_getRowsPostAsync(njsBaton *baton, napi_env env,
245245
njsVariable *var;
246246

247247
// create constructors used for various types that might be returned
248-
if (!njsBaton_setConstructors(baton, env))
248+
if (!njsBaton_setConstructors(baton, env, false))
249249
return false;
250250

251251
// if outFormat is OBJECT, create names for each of the variables

src/njsVariable.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,8 @@ bool njsVariable_setScalarValue(njsVariable *var, uint32_t pos, napi_env env,
941941
if (valueType == napi_object) {
942942

943943
// handle binding dates
944-
NJS_CHECK_NAPI(env, napi_instanceof(env, value,
945-
baton->jsDateConstructor, &check))
944+
if (!njsBaton_isDate(baton, env, value, &check))
945+
return false;
946946
if (check) {
947947
if (var->varTypeNum != DPI_ORACLE_TYPE_TIMESTAMP_LTZ)
948948
return njsVariable_setInvalidBind(var, pos, baton);

0 commit comments

Comments
 (0)