From 3204a058ab5416b776d936c2a87d24a9d99f905b Mon Sep 17 00:00:00 2001 From: Felipe Noronha Date: Fri, 22 Feb 2019 03:22:42 -0300 Subject: [PATCH] Expose dpiNumber --- include/dpi.h | 15 +++++++++++++++ src/dpiData.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/dpiImpl.h | 6 +++++- src/dpiOci.c | 19 ++++++++++++++++++- src/dpiVar.c | 10 ++++++++-- 5 files changed, 86 insertions(+), 4 deletions(-) diff --git a/include/dpi.h b/include/dpi.h index 1ba6c3c4..2ccc9bb4 100644 --- a/include/dpi.h +++ b/include/dpi.h @@ -203,6 +203,7 @@ typedef uint32_t dpiNativeTypeNum; #define DPI_NATIVE_TYPE_STMT 3010 #define DPI_NATIVE_TYPE_BOOLEAN 3011 #define DPI_NATIVE_TYPE_ROWID 3012 +#define DPI_NATIVE_TYPE_NUMBER 3013 // operation codes (database change and continuous query notification) typedef uint32_t dpiOpCode; @@ -395,6 +396,13 @@ typedef struct { int8_t tzMinuteOffset; } dpiTimestamp; +#define OCI_NUMBER_SIZE 22 + +// structure used for transferring OCINumber to/from ODPI-C +typedef struct { + uint8_t numberPart[OCI_NUMBER_SIZE]; +} dpiNumber; + //----------------------------------------------------------------------------- // Other Types @@ -444,6 +452,7 @@ typedef union { dpiObject *asObject; dpiStmt *asStmt; dpiRowid *asRowid; + dpiNumber asNumber; } dpiDataBuffer; // structure used for application context @@ -929,6 +938,9 @@ float dpiData_getFloat(dpiData *data); // return the integer portion of the data int64_t dpiData_getInt64(dpiData *data); +// return the dpiNumber portion of the data +dpiNumber dpiData_getNumber(dpiData *data); + // return the interval (days/seconds) portion of the data dpiIntervalDS *dpiData_getIntervalDS(dpiData *data); @@ -995,6 +1007,9 @@ void dpiData_setTimestamp(dpiData *data, int16_t year, uint8_t month, // set the unsigned integer portion of the data void dpiData_setUint64(dpiData *data, uint64_t value); +// set the dpiNumber portion of the data +void dpiData_setNumber(dpiData *data, dpiNumber number); + //----------------------------------------------------------------------------- // Dequeue Option Methods (dpiDeqOptions) diff --git a/src/dpiData.c b/src/dpiData.c index dc669f4b..f65c2b8a 100644 --- a/src/dpiData.c +++ b/src/dpiData.c @@ -109,6 +109,15 @@ int dpiDataBuffer__fromOracleNumberAsUnsignedInteger(dpiDataBuffer *data, DPI_OCI_NUMBER_UNSIGNED, error); } +//----------------------------------------------------------------------------- +// dpiDataBuffer__fromOracleNumberAsNumber() [INTERNAL] +// Populate the data from an OCINumber structure as an dpiNumber. +//----------------------------------------------------------------------------- +int dpiDataBuffer__fromOracleNumberAsNumber(dpiDataBuffer *data, + dpiError *error, void *oracleValue) +{ + return dpiOci__numberAssign(error, oracleValue, &data->asNumber); +} //----------------------------------------------------------------------------- // dpiDataBuffer__fromOracleNumberAsText() [INTERNAL] @@ -348,6 +357,17 @@ int dpiDataBuffer__toOracleNumberFromDouble(dpiDataBuffer *data, } +//----------------------------------------------------------------------------- +// dpiDataBuffer__toOracleNumberFromNumber() [INTERNAL] +// Populate the data in an OCINumber structure from a dpiNumber. +//----------------------------------------------------------------------------- +int dpiDataBuffer__toOracleNumberFromNumber(dpiDataBuffer *data, + dpiError *error, void *oracleValue) +{ + return dpiOci__numberAssign(error, &data->asNumber, oracleValue); +} + + //----------------------------------------------------------------------------- // dpiDataBuffer__toOracleNumberFromInteger() [INTERNAL] // Populate the data in an OCINumber structure from an integer. @@ -652,6 +672,16 @@ uint64_t dpiData_getUint64(dpiData *data) } +//----------------------------------------------------------------------------- +// dpiData_getNumber() [PUBLIC] +// Return the dpiNumber portion of the data. +//----------------------------------------------------------------------------- +dpiNumber dpiData_getNumber(dpiData *data) +{ + return data->value.asNumber; +} + + //----------------------------------------------------------------------------- // dpiData_setBool() [PUBLIC] // Set the boolean portion of the data. @@ -816,3 +846,13 @@ void dpiData_setUint64(dpiData *data, uint64_t value) data->value.asUint64 = value; } + +//----------------------------------------------------------------------------- +// dpiData_setNumber() [PUBLIC] +// Set the dpiNumber portion of the data. +//----------------------------------------------------------------------------- +void dpiData_setNumber(dpiData *data, dpiNumber number) +{ + data->isNull = 0; + data->value.asNumber = number; +} diff --git a/src/dpiImpl.h b/src/dpiImpl.h index 7b9a99a9..b1912efb 100644 --- a/src/dpiImpl.h +++ b/src/dpiImpl.h @@ -1153,6 +1153,8 @@ int dpiDataBuffer__fromOracleNumberAsDouble(dpiDataBuffer *data, dpiError *error, void *oracleValue); int dpiDataBuffer__fromOracleNumberAsInteger(dpiDataBuffer *data, dpiError *error, void *oracleValue); +int dpiDataBuffer__fromOracleNumberAsNumber(dpiDataBuffer *data, + dpiError *error, void *oracleValue); int dpiDataBuffer__fromOracleNumberAsText(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__fromOracleNumberAsUnsignedInteger(dpiDataBuffer *data, @@ -1168,6 +1170,8 @@ int dpiDataBuffer__toOracleIntervalYM(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleNumberFromDouble(dpiDataBuffer *data, dpiError *error, void *oracleValue); +int dpiDataBuffer__toOracleNumberFromNumber(dpiDataBuffer *data, + dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleNumberFromInteger(dpiDataBuffer *data, dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleNumberFromText(dpiDataBuffer *data, dpiEnv *env, @@ -1690,7 +1694,7 @@ int dpiOci__transRollback(dpiConn *conn, int checkError, dpiError *error); int dpiOci__transStart(dpiConn *conn, dpiError *error); int dpiOci__typeByFullName(dpiConn *conn, const char *name, uint32_t nameLength, void **tdo, dpiError *error); - +int dpiOci__numberAssign(dpiError *error, const void *from, void *to); //----------------------------------------------------------------------------- // definition of internal dpiMsgProps methods diff --git a/src/dpiOci.c b/src/dpiOci.c index 511af5ce..55aba1fc 100644 --- a/src/dpiOci.c +++ b/src/dpiOci.c @@ -398,7 +398,8 @@ typedef int (*dpiOciFnType__typeByFullName)(void *env, void *err, uint32_t full_type_name_length, const char *version_name, uint32_t version_name_length, uint16_t pin_duration, int get_option, void **tdo); - +typedef int (*dpiOciFnType__numberAssign)(void *err, + const void *from, void *to); // library handle for dynamically loaded OCI library static void *dpiOciLibHandle = NULL; @@ -581,6 +582,7 @@ static struct { dpiOciFnType__transRollback fnTransRollback; dpiOciFnType__transStart fnTransStart; dpiOciFnType__typeByFullName fnTypeByFullName; + dpiOciFnType__numberAssign fnNumberAssign; } dpiOciSymbols; @@ -3552,3 +3554,18 @@ int dpiOci__typeByFullName(dpiConn *conn, const char *name, DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get type by full name"); } + +//----------------------------------------------------------------------------- +// dpiOci__numberAssign() [INTERNAL] +// Wrapper for OCINumberAssign(). +//----------------------------------------------------------------------------- +int dpiOci__numberAssign(dpiError *error, const void *from, void *to) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCINumberAssign", dpiOciSymbols.fnNumberAssign) + status = (*dpiOciSymbols.fnNumberAssign)(error->handle, + from, to); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number assign"); +} + diff --git a/src/dpiVar.c b/src/dpiVar.c index de9db59b..e3a290aa 100644 --- a/src/dpiVar.c +++ b/src/dpiVar.c @@ -606,7 +606,6 @@ void dpiVar__free(dpiVar *var, dpiError *error) dpiUtils__freeMemory(var); } - //----------------------------------------------------------------------------- // dpiVar__getValue() [PRIVATE] // Returns the contents of the variable in the type specified, if possible. @@ -767,6 +766,9 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, case DPI_NATIVE_TYPE_BOOLEAN: data->value.asBoolean = buffer->data.asBoolean[pos]; break; + case DPI_NATIVE_TYPE_NUMBER: + return dpiDataBuffer__fromOracleNumberAsNumber(&data->value, + error, &buffer->data.asNumber[pos]); default: break; } @@ -1483,6 +1485,9 @@ int dpiVar__setValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, if (buffer->returnCode) buffer->returnCode[pos] = 0; break; + case DPI_NATIVE_TYPE_NUMBER: + return dpiDataBuffer__toOracleNumberFromNumber(&data->value, + error, &buffer->data.asNumber[pos]); case DPI_NATIVE_TYPE_TIMESTAMP: if (oracleTypeNum == DPI_ORACLE_TYPE_DATE) return dpiDataBuffer__toOracleDate(&data->value, @@ -1529,7 +1534,8 @@ static int dpiVar__validateTypes(const dpiOracleType *oracleType, case DPI_ORACLE_TYPE_NUMBER: if (nativeTypeNum == DPI_NATIVE_TYPE_INT64 || nativeTypeNum == DPI_NATIVE_TYPE_UINT64 || - nativeTypeNum == DPI_NATIVE_TYPE_BYTES) + nativeTypeNum == DPI_NATIVE_TYPE_BYTES || + nativeTypeNum == DPI_NATIVE_TYPE_NUMBER) return DPI_SUCCESS; break; default: