Move code from C to JS and fix fetchType
This commit is contained in:
parent
2d2fce0dda
commit
81cf2df5a4
|
@ -68,8 +68,6 @@ class Connection extends EventEmitter {
|
|||
"autoCommit",
|
||||
"dbObjectAsPojo",
|
||||
"fetchArraySize",
|
||||
"fetchAsBuffer",
|
||||
"fetchAsString",
|
||||
"maxRows",
|
||||
"outFormat",
|
||||
"prefetchRows");
|
||||
|
@ -793,10 +791,10 @@ class Connection extends EventEmitter {
|
|||
if (options.fetchInfo !== undefined) {
|
||||
errors.assertParamPropValue(nodbUtil.isObject(options.fetchInfo), 3,
|
||||
"fetchInfo");
|
||||
const keys = Object.getOwnPropertyNames(options.fetchInfo);
|
||||
outOptions.fetchInfo = new Array(keys.length);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const info = options.fetchInfo[keys[i]];
|
||||
const names = Object.getOwnPropertyNames(options.fetchInfo);
|
||||
const map = new Map(settings.fetchTypeMap);
|
||||
for (const name of names) {
|
||||
const info = options.fetchInfo[name];
|
||||
if (info.type === undefined)
|
||||
errors.throwErr(errors.ERR_NO_TYPE_FOR_CONVERSION);
|
||||
if (info.type !== constants.DEFAULT &&
|
||||
|
@ -804,8 +802,9 @@ class Connection extends EventEmitter {
|
|||
info.type !== constants.DB_TYPE_RAW) {
|
||||
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
|
||||
}
|
||||
outOptions.fetchInfo[i] = {name: keys[i], type: info.type};
|
||||
map.set(name, info.type);
|
||||
}
|
||||
outOptions.fetchTypeMap = map;
|
||||
}
|
||||
|
||||
// maxRows must be a positive integer (or 0)
|
||||
|
@ -1230,7 +1229,9 @@ class Connection extends EventEmitter {
|
|||
const info = await this._impl.getStatementInfo(sql);
|
||||
if (info.metaData) {
|
||||
for (let i = 0; i < info.metaData.length; i++) {
|
||||
nodbUtil.addTypeProperties(info.metaData[i], "dbType");
|
||||
const m = info.metaData[i];
|
||||
nodbUtil.addTypeProperties(m, "dbType");
|
||||
m.fetchType = constants.DB_TYPE_FETCH_TYPE_MAP.get(m.dbType);
|
||||
}
|
||||
}
|
||||
return info;
|
||||
|
|
|
@ -154,6 +154,36 @@ module.exports = {
|
|||
[DB_TYPE_VARCHAR, "VARCHAR2"]
|
||||
]),
|
||||
|
||||
// default fetch type map
|
||||
DB_TYPE_FETCH_TYPE_MAP: new Map([
|
||||
[DB_TYPE_BFILE, DB_TYPE_BFILE],
|
||||
[DB_TYPE_BINARY_DOUBLE, DB_TYPE_BINARY_DOUBLE],
|
||||
[DB_TYPE_BINARY_FLOAT, DB_TYPE_BINARY_FLOAT],
|
||||
[DB_TYPE_BINARY_INTEGER, DB_TYPE_BINARY_INTEGER],
|
||||
[DB_TYPE_BLOB, DB_TYPE_BLOB],
|
||||
[DB_TYPE_BOOLEAN, DB_TYPE_BOOLEAN],
|
||||
[DB_TYPE_CHAR, DB_TYPE_CHAR],
|
||||
[DB_TYPE_CLOB, DB_TYPE_CLOB],
|
||||
[DB_TYPE_CURSOR, DB_TYPE_CURSOR],
|
||||
[DB_TYPE_DATE, DB_TYPE_TIMESTAMP_LTZ],
|
||||
[DB_TYPE_INTERVAL_DS, DB_TYPE_INTERVAL_DS],
|
||||
[DB_TYPE_INTERVAL_YM, DB_TYPE_INTERVAL_YM],
|
||||
[DB_TYPE_JSON, DB_TYPE_JSON],
|
||||
[DB_TYPE_LONG, DB_TYPE_LONG],
|
||||
[DB_TYPE_LONG_RAW, DB_TYPE_LONG_RAW],
|
||||
[DB_TYPE_NCHAR, DB_TYPE_NCHAR],
|
||||
[DB_TYPE_NCLOB, DB_TYPE_NCLOB],
|
||||
[DB_TYPE_NUMBER, DB_TYPE_NUMBER],
|
||||
[DB_TYPE_NVARCHAR, DB_TYPE_NVARCHAR],
|
||||
[DB_TYPE_OBJECT, DB_TYPE_OBJECT],
|
||||
[DB_TYPE_RAW, DB_TYPE_RAW],
|
||||
[DB_TYPE_ROWID, DB_TYPE_ROWID],
|
||||
[DB_TYPE_TIMESTAMP, DB_TYPE_TIMESTAMP_LTZ],
|
||||
[DB_TYPE_TIMESTAMP_LTZ, DB_TYPE_TIMESTAMP_LTZ],
|
||||
[DB_TYPE_TIMESTAMP_TZ, DB_TYPE_TIMESTAMP_LTZ],
|
||||
[DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
|
||||
]),
|
||||
|
||||
// fetchInfo type defaulting
|
||||
DEFAULT: 0,
|
||||
|
||||
|
|
|
@ -72,6 +72,15 @@ class ResultSetImpl {
|
|||
errors.throwNotImplemented("getting rows");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// setFetchTypes()
|
||||
//
|
||||
// Sets the types to use when fetching data.
|
||||
//---------------------------------------------------------------------------
|
||||
setFetchTypes() {
|
||||
errors.throwNotImplemented("setting fetch types");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ResultSetImpl;
|
||||
|
|
|
@ -1034,26 +1034,13 @@ module.exports = {
|
|||
|
||||
set fetchAsBuffer(value) {
|
||||
errors.assertPropValue(Array.isArray(value), "fetchAsBuffer");
|
||||
for (const element of value) {
|
||||
if (element !== constants.DB_TYPE_BLOB) {
|
||||
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
|
||||
}
|
||||
}
|
||||
settings.createFetchTypeMap(settings.fetchAsString, value);
|
||||
settings.fetchAsBuffer = value;
|
||||
},
|
||||
|
||||
set fetchAsString(value) {
|
||||
errors.assertPropValue(Array.isArray(value), "fetchAsString");
|
||||
for (const element of value) {
|
||||
if (element != constants.DB_TYPE_NUMBER &&
|
||||
element != constants.DB_TYPE_TIMESTAMP_LTZ &&
|
||||
element != constants.DB_TYPE_RAW &&
|
||||
element != constants.DB_TYPE_CLOB &&
|
||||
element != constants.DB_TYPE_NCLOB &&
|
||||
element != constants.DB_TYPE_JSON) {
|
||||
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
|
||||
}
|
||||
}
|
||||
settings.createFetchTypeMap(value, settings.fetchAsBuffer);
|
||||
settings.fetchAsString = value;
|
||||
},
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ const QueryStream = require('./queryStream.js');
|
|||
const BaseDbObject = require('./dbObject.js');
|
||||
const nodbUtil = require('./util.js');
|
||||
const constants = require('./constants.js');
|
||||
const settings = require('./settings.js');
|
||||
const Lob = require('./lob.js');
|
||||
const errors = require('./errors.js');
|
||||
|
||||
|
@ -43,6 +44,23 @@ class ResultSet {
|
|||
this._isActive = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// _determineFetchType()
|
||||
//
|
||||
// Determine the fetch type to use for the specified metadata.
|
||||
//---------------------------------------------------------------------------
|
||||
_determineFetchType(metadata, options) {
|
||||
if (options.fetchTypeMap && options.fetchTypeMap.has(metadata.name)) {
|
||||
metadata.fetchType = options.fetchTypeMap.get(metadata.name);
|
||||
if (metadata.fetchType === constants.DEFAULT) {
|
||||
metadata.fetchType =
|
||||
constants.DB_TYPE_FETCH_TYPE_MAP.get(metadata.dbType);
|
||||
}
|
||||
} else {
|
||||
metadata.fetchType = settings.fetchTypeMap.get(metadata.dbType);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// _getAllRows()
|
||||
//
|
||||
|
@ -189,6 +207,7 @@ class ResultSet {
|
|||
}
|
||||
for (let i = 0; i < setupData.metaData.length; i++) {
|
||||
const info = setupData.metaData[i];
|
||||
this._determineFetchType(info, options);
|
||||
if (info.fetchType === constants.DB_TYPE_CURSOR) {
|
||||
setupData.nestedCursorSetupData.push({"index": i});
|
||||
} else if (info.fetchType === constants.DB_TYPE_CLOB ||
|
||||
|
@ -213,6 +232,7 @@ class ResultSet {
|
|||
}
|
||||
}
|
||||
}
|
||||
resultSetImpl.setFetchTypes(setupData.metaData);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -27,6 +27,7 @@
|
|||
'use strict';
|
||||
|
||||
const constants = require('./constants.js');
|
||||
const errors = require('./errors.js');
|
||||
|
||||
class Settings {
|
||||
|
||||
|
@ -54,6 +55,7 @@ class Settings {
|
|||
this.queueTimeout = 60000;
|
||||
this.queueMax = 500;
|
||||
this.stmtCacheSize = 30;
|
||||
this.createFetchTypeMap(this.fetchAsString, this.fetchAsBuffer);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -70,6 +72,66 @@ class Settings {
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// createFetchTypeMap()
|
||||
//
|
||||
// Creates the fetch type map. This overrides the default fetch type mapping
|
||||
// used by the driver with the contents of the fetchAsString and
|
||||
// fetchAsBuffer arrays. The error checking is performed here as well in
|
||||
// order to eliminate repeated code.
|
||||
// ---------------------------------------------------------------------------
|
||||
createFetchTypeMap(fetchAsString, fetchAsBuffer) {
|
||||
|
||||
// create a copy of the default fetch type map
|
||||
const map = new Map(constants.DB_TYPE_FETCH_TYPE_MAP);
|
||||
|
||||
// adjust map for fetchAsString settings
|
||||
for (const element of fetchAsString) {
|
||||
switch (element) {
|
||||
case constants.DB_TYPE_NUMBER:
|
||||
map.set(constants.DB_TYPE_BINARY_DOUBLE, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_BINARY_FLOAT, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_BINARY_INTEGER, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_NUMBER, constants.DB_TYPE_VARCHAR);
|
||||
break;
|
||||
case constants.DB_TYPE_TIMESTAMP_LTZ:
|
||||
map.set(constants.DB_TYPE_DATE, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_TIMESTAMP, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_TIMESTAMP_TZ, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_TIMESTAMP_LTZ, constants.DB_TYPE_VARCHAR);
|
||||
break;
|
||||
case constants.DB_TYPE_CLOB:
|
||||
case constants.DB_TYPE_NCLOB:
|
||||
map.set(constants.DB_TYPE_CLOB, constants.DB_TYPE_VARCHAR);
|
||||
map.set(constants.DB_TYPE_NCLOB, constants.DB_TYPE_NVARCHAR);
|
||||
break;
|
||||
case constants.DB_TYPE_RAW:
|
||||
map.set(constants.DB_TYPE_RAW, constants.DB_TYPE_VARCHAR);
|
||||
break;
|
||||
case constants.DB_TYPE_JSON:
|
||||
map.set(constants.DB_TYPE_JSON, constants.DB_TYPE_VARCHAR);
|
||||
break;
|
||||
default:
|
||||
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
|
||||
}
|
||||
}
|
||||
|
||||
// adjust map for fetchAsBuffer settings
|
||||
for (const element of fetchAsBuffer) {
|
||||
switch (element) {
|
||||
case constants.DB_TYPE_BLOB:
|
||||
map.set(constants.DB_TYPE_BLOB, constants.DB_TYPE_RAW);
|
||||
break;
|
||||
default:
|
||||
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
|
||||
}
|
||||
}
|
||||
|
||||
// assign calculated fetchTypeMap for later use
|
||||
this.fetchTypeMap = map;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = new Settings();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2015, 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2015, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -333,18 +333,6 @@ void njsBaton_free(njsBaton *baton, napi_env env)
|
|||
baton->implicitResults = baton->implicitResults->next;
|
||||
}
|
||||
|
||||
// free mapping type arrays
|
||||
if (baton->fetchInfo) {
|
||||
for (i = 0; i < baton->numFetchInfo; i++) {
|
||||
NJS_FREE_AND_CLEAR(baton->fetchInfo[i].name);
|
||||
}
|
||||
free(baton->fetchInfo);
|
||||
baton->fetchInfo = NULL;
|
||||
}
|
||||
|
||||
NJS_FREE_AND_CLEAR(baton->fetchAsStringTypes);
|
||||
NJS_FREE_AND_CLEAR(baton->fetchAsBufferTypes);
|
||||
|
||||
// remove references to JS objects
|
||||
NJS_DELETE_REF_AND_CLEAR(baton->jsBufferRef);
|
||||
NJS_DELETE_REF_AND_CLEAR(baton->jsCallingObjRef);
|
||||
|
@ -423,53 +411,6 @@ static bool njsBaton_getErrorInfo(njsBaton *baton, napi_env env,
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsBaton_getFetchInfoFromArg()
|
||||
// Gets fetchInfo data from the specified Javascript object property, if
|
||||
// possible. If the given property is undefined, no error is set and the value
|
||||
// is left untouched; otherwise, if the value is not valid, an error is set on
|
||||
// the baton.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsBaton_getFetchInfoFromArg(njsBaton *baton, napi_env env,
|
||||
napi_value props, uint32_t *numFetchInfo, njsFetchInfo **fetchInfo)
|
||||
{
|
||||
napi_value value, element, temp;
|
||||
njsFetchInfo *tempFetchInfo;
|
||||
uint32_t i;
|
||||
|
||||
// determine number of fetch info; if none, nothing more to do!
|
||||
NJS_CHECK_NAPI(env, napi_get_named_property(env, props, "fetchInfo",
|
||||
&value))
|
||||
NJS_CHECK_NAPI(env, napi_get_array_length(env, value, numFetchInfo))
|
||||
if (*numFetchInfo == 0) {
|
||||
*fetchInfo = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
// allocate space for fetchInfo structures
|
||||
tempFetchInfo = calloc(*numFetchInfo, sizeof(njsFetchInfo));
|
||||
if (!tempFetchInfo)
|
||||
return njsBaton_setErrorInsufficientMemory(baton);
|
||||
*fetchInfo = tempFetchInfo;
|
||||
|
||||
// process each key
|
||||
for (i = 0; i < *numFetchInfo; i++) {
|
||||
NJS_CHECK_NAPI(env, napi_get_element(env, value, i, &element))
|
||||
NJS_CHECK_NAPI(env, napi_get_named_property(env, element, "name",
|
||||
&temp))
|
||||
if (!njsUtils_copyStringFromJS(env, temp, &tempFetchInfo[i].name,
|
||||
&tempFetchInfo[i].nameLength))
|
||||
return false;
|
||||
NJS_CHECK_NAPI(env, napi_get_named_property(env, element, "type",
|
||||
&temp))
|
||||
NJS_CHECK_NAPI(env, napi_get_value_uint32(env, temp,
|
||||
&tempFetchInfo[i].type))
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsBaton_getNumOutBinds()
|
||||
// Return the number of IN/OUT and OUT binds created by the baton.
|
||||
|
@ -703,21 +644,6 @@ bool njsBaton_setErrorInsufficientMemory(njsBaton *baton)
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsBaton_setErrorUnsupportedDataType()
|
||||
// Set the error on the baton to indicate that an unsupported data type was
|
||||
// encountered during a fetch. Returns false as a convenience to the caller.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsBaton_setErrorUnsupportedDataType(njsBaton *baton,
|
||||
uint32_t oracleTypeNum, uint32_t columnNum)
|
||||
{
|
||||
(void) snprintf(baton->error, sizeof(baton->error),
|
||||
NJS_ERR_UNSUPPORTED_DATA_TYPE, oracleTypeNum, columnNum);
|
||||
baton->hasError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsBaton_setErrorUnsupportedDataTypeInJson()
|
||||
// Set the error on the baton to indicate that an unsupported data type was
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2015, 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2015, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -574,14 +574,6 @@ NJS_NAPI_METHOD_IMPL_ASYNC(njsConnection_execute, 5, NULL)
|
|||
&baton->dmlRowCounts))
|
||||
return false;
|
||||
} else {
|
||||
if (!njsUtils_getNamedPropertyUnsignedIntArray(env, args[3],
|
||||
"fetchAsBuffer", &baton->numFetchAsBufferTypes,
|
||||
&baton->fetchAsBufferTypes))
|
||||
return false;
|
||||
if (!njsUtils_getNamedPropertyUnsignedIntArray(env, args[3],
|
||||
"fetchAsString", &baton->numFetchAsStringTypes,
|
||||
&baton->fetchAsStringTypes))
|
||||
return false;
|
||||
NJS_CHECK_NAPI(env, napi_get_named_property(env, args[3],
|
||||
"fetchArraySize", &temp))
|
||||
NJS_CHECK_NAPI(env, napi_get_value_uint32(env, temp,
|
||||
|
@ -590,9 +582,6 @@ NJS_NAPI_METHOD_IMPL_ASYNC(njsConnection_execute, 5, NULL)
|
|||
"prefetchRows", &temp))
|
||||
NJS_CHECK_NAPI(env, napi_get_value_uint32(env, temp,
|
||||
&baton->prefetchRows))
|
||||
if (!njsBaton_getFetchInfoFromArg(baton, env, args[3],
|
||||
&baton->numFetchInfo, &baton->fetchInfo))
|
||||
return false;
|
||||
}
|
||||
NJS_CHECK_NAPI(env, napi_get_named_property(env, args[3], "autoCommit",
|
||||
&temp))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019, 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2019, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -198,7 +198,6 @@ typedef struct njsBaton njsBaton;
|
|||
typedef struct njsClassDef njsClassDef;
|
||||
typedef struct njsConnection njsConnection;
|
||||
typedef struct njsDataTypeInfo njsDataTypeInfo;
|
||||
typedef struct njsFetchInfo njsFetchInfo;
|
||||
typedef struct njsImplicitResult njsImplicitResult;
|
||||
typedef struct njsJsonBuffer njsJsonBuffer;
|
||||
typedef struct njsLob njsLob;
|
||||
|
@ -369,14 +368,6 @@ struct njsBaton {
|
|||
uint32_t numRowCounts;
|
||||
uint64_t *rowCounts;
|
||||
|
||||
// mapping types (requires free)
|
||||
uint32_t numFetchInfo;
|
||||
njsFetchInfo *fetchInfo;
|
||||
uint32_t numFetchAsStringTypes;
|
||||
uint32_t *fetchAsStringTypes;
|
||||
uint32_t numFetchAsBufferTypes;
|
||||
uint32_t *fetchAsBufferTypes;
|
||||
|
||||
// implicit results (requires free)
|
||||
njsImplicitResult *implicitResults;
|
||||
|
||||
|
@ -493,13 +484,6 @@ struct njsConnection {
|
|||
bool retag;
|
||||
};
|
||||
|
||||
// data for adjusting fetch types
|
||||
struct njsFetchInfo {
|
||||
char *name;
|
||||
size_t nameLength;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
// data for acquiring implicit results
|
||||
struct njsImplicitResult {
|
||||
dpiStmt *stmt;
|
||||
|
@ -730,8 +714,6 @@ bool njsBaton_commonConnectProcessArgs(njsBaton *baton, napi_env env,
|
|||
bool njsBaton_create(njsBaton *baton, napi_env env, napi_callback_info info,
|
||||
size_t numArgs, napi_value *args, const njsClassDef *classDef);
|
||||
void njsBaton_free(njsBaton *baton, napi_env env);
|
||||
bool njsBaton_getFetchInfoFromArg(njsBaton *baton, napi_env env,
|
||||
napi_value props, uint32_t *numFetchInfo, njsFetchInfo **fetchInfo);
|
||||
uint32_t njsBaton_getNumOutBinds(njsBaton *baton);
|
||||
bool njsBaton_getSodaDocument(njsBaton *baton, njsSodaDatabase *db,
|
||||
napi_env env, napi_value obj, dpiSodaDoc **handle);
|
||||
|
@ -893,8 +875,10 @@ bool njsUtils_getNamedPropertyUnsignedIntArray(napi_env env, napi_value value,
|
|||
const char *name, uint32_t *numElements, uint32_t **elements);
|
||||
bool njsUtils_getXid(napi_env env, napi_value xidObj, dpiXid **xid);
|
||||
bool njsUtils_isInstance(napi_env env, napi_value value, const char *name);
|
||||
bool njsUtils_throwInsufficientMemory(napi_env env);
|
||||
bool njsUtils_throwErrorDPI(napi_env env, njsModuleGlobals *globals);
|
||||
bool njsUtils_throwInsufficientMemory(napi_env env);
|
||||
bool njsUtils_throwUnsupportedDataType(napi_env env, uint32_t oracleTypeNum,
|
||||
uint32_t columnNum);
|
||||
bool njsUtils_validateArgs(napi_env env, napi_callback_info info,
|
||||
size_t numArgs, napi_value *args, njsModuleGlobals **globals,
|
||||
napi_value *callingObj, const njsClassDef *classDef, void **instance);
|
||||
|
@ -919,8 +903,6 @@ bool njsVariable_initForQuery(njsVariable *vars, uint32_t numVars,
|
|||
dpiStmt *handle, njsBaton *baton);
|
||||
bool njsVariable_initForQueryJS(njsVariable *vars, uint32_t numVars,
|
||||
napi_env env, njsBaton *baton);
|
||||
bool njsVariable_performMapping(njsVariable *var, dpiQueryInfo *queryInfo,
|
||||
njsBaton *baton);
|
||||
bool njsVariable_process(njsVariable *vars, uint32_t numVars, uint32_t numRows,
|
||||
njsBaton *baton);
|
||||
bool njsVariable_processJS(njsVariable *vars, uint32_t numVars, napi_env env,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2015, 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2015, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -36,6 +36,7 @@
|
|||
NJS_NAPI_METHOD_DECL_ASYNC(njsResultSet_close);
|
||||
NJS_NAPI_METHOD_DECL_SYNC(njsResultSet_getMetaData);
|
||||
NJS_NAPI_METHOD_DECL_ASYNC(njsResultSet_getRows);
|
||||
NJS_NAPI_METHOD_DECL_SYNC(njsResultSet_setFetchTypes);
|
||||
|
||||
// asynchronous methods
|
||||
static NJS_ASYNC_METHOD(njsResultSet_closeAsync);
|
||||
|
@ -55,6 +56,8 @@ static const napi_property_descriptor njsClassProperties[] = {
|
|||
napi_default, NULL },
|
||||
{ "getRows", NULL, njsResultSet_getRows, NULL, NULL, NULL, napi_default,
|
||||
NULL },
|
||||
{ "setFetchTypes", NULL, njsResultSet_setFetchTypes, NULL, NULL, NULL,
|
||||
napi_default, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL, napi_default, NULL }
|
||||
};
|
||||
|
||||
|
@ -181,12 +184,9 @@ static bool njsResultSet_getRowsAsync(njsBaton *baton)
|
|||
return njsBaton_setErrorDPI(baton);
|
||||
var->dpiVarHandle = NULL;
|
||||
}
|
||||
if (dpiConn_newVar(rs->conn->handle, var->varTypeNum,
|
||||
var->nativeTypeNum, baton->fetchArraySize, var->maxSize, 1, 0,
|
||||
var->dpiObjectTypeHandle, &var->dpiVarHandle,
|
||||
&var->buffer->dpiVarData) < 0)
|
||||
return njsBaton_setErrorDPI(baton);
|
||||
var->maxArraySize = baton->fetchArraySize;
|
||||
if (!njsVariable_createBuffer(var, rs->conn, baton))
|
||||
return false;
|
||||
}
|
||||
|
||||
// perform define, if necessary
|
||||
|
@ -306,3 +306,76 @@ bool njsResultSet_new(njsBaton *baton, napi_env env, njsConnection *conn,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsResultSet_setFetchTypes()
|
||||
// Get accessor of "metaData" property.
|
||||
//-----------------------------------------------------------------------------
|
||||
NJS_NAPI_METHOD_IMPL_SYNC(njsResultSet_setFetchTypes, 1, NULL)
|
||||
{
|
||||
njsResultSet *rs = (njsResultSet*) callingInstance;
|
||||
napi_value metadata, temp;
|
||||
njsVariable *var;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < rs->numQueryVars; i++) {
|
||||
var = &rs->queryVars[i];
|
||||
|
||||
// determine fetch type to use
|
||||
NJS_CHECK_NAPI(env, napi_get_element(env, args[0], i, &metadata))
|
||||
NJS_CHECK_NAPI(env, napi_get_named_property(env, metadata, "fetchType",
|
||||
&temp))
|
||||
NJS_CHECK_NAPI(env, napi_get_value_uint32(env, temp, &var->varTypeNum))
|
||||
|
||||
// if RAW data is being returned as VARCHAR, need to have twice as much
|
||||
// space available to account for the hex encoding that the server does
|
||||
if (var->dbTypeNum == DPI_ORACLE_TYPE_RAW &&
|
||||
var->varTypeNum == DPI_ORACLE_TYPE_VARCHAR) {
|
||||
var->maxSize *= 2;
|
||||
}
|
||||
|
||||
// adjust max size to use based on fetch type and verify fetch type
|
||||
switch (var->varTypeNum) {
|
||||
case DPI_ORACLE_TYPE_VARCHAR:
|
||||
case DPI_ORACLE_TYPE_NVARCHAR:
|
||||
case DPI_ORACLE_TYPE_CHAR:
|
||||
case DPI_ORACLE_TYPE_NCHAR:
|
||||
case DPI_ORACLE_TYPE_RAW:
|
||||
if (var->dbTypeNum == DPI_ORACLE_TYPE_CLOB ||
|
||||
var->dbTypeNum == DPI_ORACLE_TYPE_NCLOB ||
|
||||
var->dbTypeNum == DPI_ORACLE_TYPE_BLOB) {
|
||||
var->maxSize = (uint32_t) -1;
|
||||
} else if (var->maxSize == 0) {
|
||||
var->maxSize = NJS_MAX_FETCH_AS_STRING_SIZE;
|
||||
}
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_LONG_VARCHAR:
|
||||
case DPI_ORACLE_TYPE_LONG_RAW:
|
||||
var->maxSize = (uint32_t) -1;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_DATE:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
|
||||
case DPI_ORACLE_TYPE_CLOB:
|
||||
case DPI_ORACLE_TYPE_NCLOB:
|
||||
case DPI_ORACLE_TYPE_BLOB:
|
||||
case DPI_ORACLE_TYPE_OBJECT:
|
||||
case DPI_ORACLE_TYPE_NUMBER:
|
||||
case DPI_ORACLE_TYPE_NATIVE_INT:
|
||||
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
|
||||
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
|
||||
case DPI_ORACLE_TYPE_ROWID:
|
||||
case DPI_ORACLE_TYPE_STMT:
|
||||
case DPI_ORACLE_TYPE_JSON:
|
||||
break;
|
||||
default:
|
||||
return njsUtils_throwUnsupportedDataType(env, var->varTypeNum,
|
||||
i + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2015, 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2015, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -533,46 +533,6 @@ bool njsUtils_getNamedPropertyUnsignedInt(napi_env env, napi_value value,
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_getNamedPropertyUnsignedIntArray()
|
||||
// Returns the value of the named property, which is assumed to be an array
|
||||
// of unsigned integers. If the value is not found, the array is left
|
||||
// unchanged.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsUtils_getNamedPropertyUnsignedIntArray(napi_env env, napi_value value,
|
||||
const char *name, uint32_t *numElements, uint32_t **elements)
|
||||
{
|
||||
napi_value array, element;
|
||||
uint32_t i;
|
||||
|
||||
// get value of the named property, if not found, nothing to do
|
||||
if (!njsUtils_getNamedProperty(env, value, name, &array))
|
||||
return false;
|
||||
if (!array)
|
||||
return true;
|
||||
|
||||
// free memory, if applicable
|
||||
if (*elements) {
|
||||
free(*elements);
|
||||
*elements = NULL;
|
||||
*numElements = 0;
|
||||
}
|
||||
|
||||
// get the elements from the array
|
||||
NJS_CHECK_NAPI(env, napi_get_array_length(env, array, numElements))
|
||||
*elements = calloc(*numElements, sizeof(uint32_t));
|
||||
if (!elements && *numElements > 0)
|
||||
return njsUtils_throwInsufficientMemory(env);
|
||||
for (i = 0; i < *numElements; i++) {
|
||||
NJS_CHECK_NAPI(env, napi_get_element(env, array, i, &element))
|
||||
NJS_CHECK_NAPI(env, napi_get_value_uint32(env, element,
|
||||
&((*elements)[i])))
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_getXid()
|
||||
// Returns the XID from the specified N-API value.
|
||||
|
@ -620,18 +580,6 @@ bool njsUtils_getXid(napi_env env, napi_value value, dpiXid **xid)
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_throwInsufficientMemory()
|
||||
// Throw an error indicating that insufficient memory could be allocated. The
|
||||
// value false is returned as a convenience to the caller.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsUtils_throwInsufficientMemory(napi_env env)
|
||||
{
|
||||
napi_throw_error(env, NULL, NJS_ERR_INSUFFICIENT_MEMORY);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_throwErrorDPI()
|
||||
// Get the error message from ODPI-C and throw an equivalent JavaScript
|
||||
|
@ -650,6 +598,35 @@ bool njsUtils_throwErrorDPI(napi_env env, njsModuleGlobals *globals)
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_throwInsufficientMemory()
|
||||
// Throw an error indicating that insufficient memory could be allocated. The
|
||||
// value false is returned as a convenience to the caller.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsUtils_throwInsufficientMemory(napi_env env)
|
||||
{
|
||||
napi_throw_error(env, NULL, NJS_ERR_INSUFFICIENT_MEMORY);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_throwUnsupportedDataType()
|
||||
// Set the error on the baton to indicate that an unsupported data type was
|
||||
// encountered during a fetch. Returns false as a convenience to the caller.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsUtils_throwUnsupportedDataType(napi_env env, uint32_t oracleTypeNum,
|
||||
uint32_t columnNum)
|
||||
{
|
||||
char errorMessage[100];
|
||||
|
||||
(void) snprintf(errorMessage, sizeof(errorMessage),
|
||||
NJS_ERR_UNSUPPORTED_DATA_TYPE, oracleTypeNum, columnNum);
|
||||
napi_throw_error(env, NULL, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsUtils_validateArgs()
|
||||
// Gets the instance associated with the object and gets the arguments as
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019, 2022, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2019, 2023, Oracle and/or its affiliates.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -56,6 +56,9 @@ bool njsVariable_createBuffer(njsVariable *var, njsConnection *conn,
|
|||
case DPI_ORACLE_TYPE_NVARCHAR:
|
||||
case DPI_ORACLE_TYPE_CHAR:
|
||||
case DPI_ORACLE_TYPE_NCHAR:
|
||||
case DPI_ORACLE_TYPE_RAW:
|
||||
case DPI_ORACLE_TYPE_LONG_VARCHAR:
|
||||
case DPI_ORACLE_TYPE_LONG_RAW:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_BYTES;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
|
||||
|
@ -74,13 +77,8 @@ bool njsVariable_createBuffer(njsVariable *var, njsConnection *conn,
|
|||
case DPI_ORACLE_TYPE_STMT:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_STMT;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_RAW:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_BYTES;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_CLOB:
|
||||
case DPI_ORACLE_TYPE_NCLOB:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_LOB;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_BLOB:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_LOB;
|
||||
break;
|
||||
|
@ -96,6 +94,9 @@ bool njsVariable_createBuffer(njsVariable *var, njsConnection *conn,
|
|||
case DPI_ORACLE_TYPE_NATIVE_INT:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_INT64;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_ROWID:
|
||||
var->nativeTypeNum = DPI_NATIVE_TYPE_ROWID;
|
||||
break;
|
||||
}
|
||||
|
||||
// allocate buffer
|
||||
|
@ -212,53 +213,6 @@ bool njsVariable_getArrayValue(njsVariable *var, njsConnection *conn,
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsVariable_getDataType()
|
||||
// Return the data type that is being used by the variable. This is an
|
||||
// enumeration that is publicly available in JavaScript.
|
||||
//-----------------------------------------------------------------------------
|
||||
static uint32_t njsVariable_getDataType(njsVariable *var)
|
||||
{
|
||||
switch (var->varTypeNum) {
|
||||
case DPI_ORACLE_TYPE_VARCHAR:
|
||||
case DPI_ORACLE_TYPE_NVARCHAR:
|
||||
case DPI_ORACLE_TYPE_CHAR:
|
||||
case DPI_ORACLE_TYPE_NCHAR:
|
||||
case DPI_ORACLE_TYPE_ROWID:
|
||||
case DPI_ORACLE_TYPE_LONG_VARCHAR:
|
||||
return NJS_DATATYPE_STR;
|
||||
case DPI_ORACLE_TYPE_RAW:
|
||||
case DPI_ORACLE_TYPE_LONG_RAW:
|
||||
return NJS_DATATYPE_BUFFER;
|
||||
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
|
||||
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
|
||||
case DPI_ORACLE_TYPE_NATIVE_INT:
|
||||
case DPI_ORACLE_TYPE_NUMBER:
|
||||
return NJS_DATATYPE_NUM;
|
||||
case DPI_ORACLE_TYPE_DATE:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
|
||||
return NJS_DATATYPE_DATE;
|
||||
case DPI_ORACLE_TYPE_CLOB:
|
||||
return NJS_DATATYPE_CLOB;
|
||||
case DPI_ORACLE_TYPE_NCLOB:
|
||||
return NJS_DATATYPE_NCLOB;
|
||||
case DPI_ORACLE_TYPE_BLOB:
|
||||
return NJS_DATATYPE_BLOB;
|
||||
case DPI_ORACLE_TYPE_OBJECT:
|
||||
return NJS_DATATYPE_OBJECT;
|
||||
case DPI_ORACLE_TYPE_STMT:
|
||||
return NJS_DATATYPE_CURSOR;
|
||||
case DPI_ORACLE_TYPE_JSON:
|
||||
return NJS_DATATYPE_JSON;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NJS_DATATYPE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsVariable_getMetadataMany()
|
||||
// Return metadata about many variables.
|
||||
|
@ -300,12 +254,6 @@ bool njsVariable_getMetadataOne(njsVariable *var, napi_env env,
|
|||
var->nameLength, &temp))
|
||||
NJS_CHECK_NAPI(env, napi_set_named_property(env, *metadata, "name", temp))
|
||||
|
||||
// store JavaScript fetch type
|
||||
NJS_CHECK_NAPI(env, napi_create_uint32(env, njsVariable_getDataType(var),
|
||||
&temp))
|
||||
NJS_CHECK_NAPI(env, napi_set_named_property(env, *metadata, "fetchType",
|
||||
temp))
|
||||
|
||||
// store database type, name and class, as needed
|
||||
if (!njsUtils_addTypeProperties(env, *metadata, "dbType",
|
||||
var->dbTypeNum, var->objectType))
|
||||
|
@ -552,15 +500,7 @@ bool njsVariable_initForQuery(njsVariable *vars, uint32_t numVars,
|
|||
dpiQueryInfo queryInfo;
|
||||
uint32_t i;
|
||||
|
||||
// populate variables with query metadata
|
||||
for (i = 0; i < numVars; i++) {
|
||||
|
||||
// allocate buffer
|
||||
vars[i].buffer = calloc(1, sizeof(njsVariable));
|
||||
if (!vars[i].buffer)
|
||||
return njsBaton_setErrorInsufficientMemory(baton);
|
||||
|
||||
// get query information for the specified column
|
||||
vars[i].pos = i + 1;
|
||||
vars[i].isArray = false;
|
||||
vars[i].bindDir = NJS_BIND_OUT;
|
||||
|
@ -573,86 +513,14 @@ bool njsVariable_initForQuery(njsVariable *vars, uint32_t numVars,
|
|||
vars[i].nameLength = queryInfo.nameLength;
|
||||
vars[i].maxArraySize = baton->fetchArraySize;
|
||||
vars[i].dbSizeInBytes = queryInfo.typeInfo.dbSizeInBytes;
|
||||
vars[i].maxSize = queryInfo.typeInfo.clientSizeInBytes;
|
||||
vars[i].precision = queryInfo.typeInfo.precision +
|
||||
queryInfo.typeInfo.fsPrecision;
|
||||
vars[i].scale = queryInfo.typeInfo.scale;
|
||||
vars[i].isNullable = queryInfo.nullOk;
|
||||
|
||||
// determine the type of data
|
||||
vars[i].dbTypeNum = queryInfo.typeInfo.oracleTypeNum;
|
||||
vars[i].varTypeNum = queryInfo.typeInfo.oracleTypeNum;
|
||||
vars[i].nativeTypeNum = queryInfo.typeInfo.defaultNativeTypeNum;
|
||||
if (queryInfo.typeInfo.oracleTypeNum != DPI_ORACLE_TYPE_VARCHAR &&
|
||||
queryInfo.typeInfo.oracleTypeNum != DPI_ORACLE_TYPE_NVARCHAR &&
|
||||
queryInfo.typeInfo.oracleTypeNum != DPI_ORACLE_TYPE_CHAR &&
|
||||
queryInfo.typeInfo.oracleTypeNum != DPI_ORACLE_TYPE_NCHAR &&
|
||||
queryInfo.typeInfo.oracleTypeNum != DPI_ORACLE_TYPE_ROWID) {
|
||||
if (!njsVariable_performMapping(&vars[i], &queryInfo, baton))
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate data type and determine size
|
||||
if (vars[i].varTypeNum == DPI_ORACLE_TYPE_VARCHAR ||
|
||||
vars[i].varTypeNum == DPI_ORACLE_TYPE_NVARCHAR ||
|
||||
vars[i].varTypeNum == DPI_ORACLE_TYPE_RAW) {
|
||||
vars[i].maxSize = NJS_MAX_FETCH_AS_STRING_SIZE;
|
||||
vars[i].nativeTypeNum = DPI_NATIVE_TYPE_BYTES;
|
||||
} else {
|
||||
vars[i].maxSize = 0;
|
||||
}
|
||||
switch (queryInfo.typeInfo.oracleTypeNum) {
|
||||
case DPI_ORACLE_TYPE_VARCHAR:
|
||||
case DPI_ORACLE_TYPE_NVARCHAR:
|
||||
case DPI_ORACLE_TYPE_CHAR:
|
||||
case DPI_ORACLE_TYPE_NCHAR:
|
||||
case DPI_ORACLE_TYPE_RAW:
|
||||
vars[i].maxSize = queryInfo.typeInfo.clientSizeInBytes;
|
||||
if (queryInfo.typeInfo.oracleTypeNum == DPI_ORACLE_TYPE_RAW &&
|
||||
vars[i].varTypeNum == DPI_ORACLE_TYPE_VARCHAR)
|
||||
vars[i].maxSize *= 2;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_DATE:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
|
||||
if (vars[i].varTypeNum != DPI_ORACLE_TYPE_VARCHAR) {
|
||||
vars[i].varTypeNum = DPI_ORACLE_TYPE_TIMESTAMP_LTZ;
|
||||
vars[i].nativeTypeNum = DPI_NATIVE_TYPE_DOUBLE;
|
||||
}
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_CLOB:
|
||||
case DPI_ORACLE_TYPE_NCLOB:
|
||||
if (vars[i].varTypeNum == DPI_ORACLE_TYPE_VARCHAR ||
|
||||
vars[i].varTypeNum == DPI_ORACLE_TYPE_NVARCHAR)
|
||||
vars[i].maxSize = (uint32_t) -1;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_BLOB:
|
||||
if (vars[i].varTypeNum == DPI_ORACLE_TYPE_RAW)
|
||||
vars[i].maxSize = (uint32_t) -1;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_LONG_VARCHAR:
|
||||
case DPI_ORACLE_TYPE_LONG_RAW:
|
||||
vars[i].maxSize = (uint32_t) -1;
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_OBJECT:
|
||||
vars[i].dpiObjectTypeHandle = queryInfo.typeInfo.objectType;
|
||||
break;
|
||||
|
||||
// the remaining types are valid but no special processing needs to
|
||||
// be done
|
||||
case DPI_ORACLE_TYPE_NUMBER:
|
||||
case DPI_ORACLE_TYPE_NATIVE_INT:
|
||||
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
|
||||
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
|
||||
case DPI_ORACLE_TYPE_ROWID:
|
||||
case DPI_ORACLE_TYPE_STMT:
|
||||
case DPI_ORACLE_TYPE_JSON:
|
||||
break;
|
||||
default:
|
||||
return njsBaton_setErrorUnsupportedDataType(baton,
|
||||
queryInfo.typeInfo.oracleTypeNum, i + 1);
|
||||
}
|
||||
|
||||
if (queryInfo.typeInfo.objectType)
|
||||
vars[i].dpiObjectTypeHandle = queryInfo.typeInfo.objectType;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -683,102 +551,6 @@ bool njsVariable_initForQueryJS(njsVariable *vars, uint32_t numVars,
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsVariable_performMapping()
|
||||
// Apply any mapping rules that have been specified.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool njsVariable_performMapping(njsVariable *var, dpiQueryInfo *queryInfo,
|
||||
njsBaton *baton)
|
||||
{
|
||||
uint32_t i, oracleTypeNum = queryInfo->typeInfo.oracleTypeNum;
|
||||
|
||||
// apply "by-name" rules
|
||||
for (i = 0; i < baton->numFetchInfo; i++) {
|
||||
|
||||
// ignore rule if the name does not match
|
||||
if (queryInfo->nameLength != baton->fetchInfo[i].nameLength)
|
||||
continue;
|
||||
if (strncmp(queryInfo->name, baton->fetchInfo[i].name,
|
||||
queryInfo->nameLength) != 0)
|
||||
continue;
|
||||
|
||||
// perform any mapping specified
|
||||
if (baton->fetchInfo[i].type == NJS_DATATYPE_STR) {
|
||||
var->varTypeNum = (oracleTypeNum == DPI_ORACLE_TYPE_NCLOB) ?
|
||||
DPI_ORACLE_TYPE_NVARCHAR : DPI_ORACLE_TYPE_VARCHAR;
|
||||
} else if (baton->fetchInfo[i].type == NJS_DATATYPE_BUFFER) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_RAW;
|
||||
} else if (baton->fetchInfo[i].type == NJS_DATATYPE_DEFAULT) {
|
||||
var->varTypeNum = queryInfo->typeInfo.oracleTypeNum;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// apply fetchAsString rules
|
||||
for (i = 0; i < baton->numFetchAsStringTypes; i++) {
|
||||
switch (oracleTypeNum) {
|
||||
case DPI_ORACLE_TYPE_NUMBER:
|
||||
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
|
||||
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
|
||||
case DPI_ORACLE_TYPE_NATIVE_INT:
|
||||
if (baton->fetchAsStringTypes[i] == NJS_DATATYPE_NUM) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_VARCHAR;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_DATE:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
|
||||
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
|
||||
if (baton->fetchAsStringTypes[i] == NJS_DATATYPE_DATE) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_VARCHAR;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_CLOB:
|
||||
case DPI_ORACLE_TYPE_NCLOB:
|
||||
if (baton->fetchAsStringTypes[i] == NJS_DATATYPE_CLOB) {
|
||||
var->varTypeNum = (oracleTypeNum == DPI_ORACLE_TYPE_CLOB) ?
|
||||
DPI_ORACLE_TYPE_VARCHAR : DPI_ORACLE_TYPE_NVARCHAR;
|
||||
return true;
|
||||
}
|
||||
if (baton->fetchAsStringTypes[i] == NJS_DATATYPE_NCLOB) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_NVARCHAR;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_RAW:
|
||||
if (baton->fetchAsStringTypes[i] == NJS_DATATYPE_BUFFER) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_VARCHAR;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DPI_ORACLE_TYPE_JSON:
|
||||
if (baton->fetchAsStringTypes[i] == NJS_DATATYPE_JSON) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_VARCHAR;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// apply fetchAsBuffer rules
|
||||
for (i = 0; i < baton->numFetchAsBufferTypes; i++) {
|
||||
if (queryInfo->typeInfo.oracleTypeNum == DPI_ORACLE_TYPE_BLOB &&
|
||||
baton->fetchAsBufferTypes[i] == NJS_DATATYPE_BLOB) {
|
||||
var->varTypeNum = DPI_ORACLE_TYPE_RAW;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsVariable_process()
|
||||
// Process variables used during binding or fetching. REF cursors must have
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
|
||||
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
|
@ -740,7 +740,7 @@ describe('4. binding.js', function() {
|
|||
const cursor = result.outBinds.cursor;
|
||||
const expectedBind = {
|
||||
name: "STRINGVALUE",
|
||||
fetchType: oracledb.DB_TYPE_VARCHAR,
|
||||
fetchType: oracledb.DB_TYPE_CHAR,
|
||||
dbType: oracledb.DB_TYPE_CHAR,
|
||||
dbTypeName: "CHAR",
|
||||
nullable: true,
|
||||
|
|
Loading…
Reference in New Issue