From 469f4cba82f9728754e1e8dcfd3123eb5302d188 Mon Sep 17 00:00:00 2001 From: Elias Ohm Date: Thu, 4 Oct 2018 13:30:17 +0200 Subject: [PATCH 1/3] implement (LONG VAR)RAW/BINARY attributes for Objects - first try without changing signatures of existing functions --- src/dpiImpl.h | 2 ++ src/dpiObject.c | 27 +++++++++++++++++++++++++++ src/dpiOracleType.c | 1 + 3 files changed, 30 insertions(+) diff --git a/src/dpiImpl.h b/src/dpiImpl.h index 067e7e47..290b4a14 100644 --- a/src/dpiImpl.h +++ b/src/dpiImpl.h @@ -313,6 +313,7 @@ extern unsigned long dpiDebugLevel; #define DPI_SQLT_BIN 23 #define DPI_SQLT_LBI 24 #define DPI_SQLT_UIN 68 +#define DPI_SQLT_LVB 95 #define DPI_SQLT_AFC 96 #define DPI_SQLT_IBFLOAT 100 #define DPI_SQLT_IBDOUBLE 101 @@ -777,6 +778,7 @@ typedef union { void **asInterval; void **asLobLocator; void **asString; + void **asOciraw; void **asStmt; void **asRowid; int *asBoolean; diff --git a/src/dpiObject.c b/src/dpiObject.c index 2aabd9ec..d9c651c7 100644 --- a/src/dpiObject.c +++ b/src/dpiObject.c @@ -105,6 +105,11 @@ static void dpiObject__clearOracleValue(dpiObject *obj, dpiError *error, dpiOci__stringResize(obj->env->handle, &buffer->asString, 0, error); break; + case DPI_ORACLE_TYPE_RAW: + if (buffer->asRaw) + dpiOci__rawResize(obj->env->handle, &buffer->asRaw, 0, + error); + break; case DPI_ORACLE_TYPE_TIMESTAMP: if (buffer->asTimestamp) dpiOci__descriptorFree(buffer->asTimestamp, @@ -243,6 +248,17 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, return DPI_SUCCESS; } break; + case DPI_ORACLE_TYPE_RAW: + if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) { + asBytes = &data->value.asBytes; + dpiOci__rawPtr(obj->env->handle, *value->asOciraw, + &asBytes->ptr); + dpiOci__rawSize(obj->env->handle, *value->asOciraw, + &asBytes->length); + asBytes->encoding = NULL; + return DPI_SUCCESS; + } + break; case DPI_ORACLE_TYPE_NATIVE_INT: if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) return dpiDataBuffer__fromOracleNumberAsInteger(&data->value, @@ -385,6 +401,17 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, return DPI_SUCCESS; } break; + case DPI_ORACLE_TYPE_RAW: + buffer->asRaw = NULL; + if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) { + bytes = &data->value.asBytes; + if (dpiOci__rawAssignBytes(obj->env->handle, bytes->ptr, + bytes->length, &buffer->asRaw, error) < 0) + return DPI_FAILURE; + *ociValue = buffer->asRaw; + return DPI_SUCCESS; + } + break; case DPI_ORACLE_TYPE_NATIVE_INT: case DPI_ORACLE_TYPE_NUMBER: *ociValue = &buffer->asNumber; diff --git a/src/dpiOracleType.c b/src/dpiOracleType.c index e22d20fc..595e31cc 100644 --- a/src/dpiOracleType.c +++ b/src/dpiOracleType.c @@ -309,6 +309,7 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, case DPI_SQLT_ODT: return DPI_ORACLE_TYPE_DATE; case DPI_SQLT_BIN: + case DPI_SQLT_LVB: return DPI_ORACLE_TYPE_RAW; case DPI_SQLT_AFC: if (charsetForm == DPI_SQLCS_NCHAR) From 47367fe4eca82f89acac2883dec0ef2d4fe9107a Mon Sep 17 00:00:00 2001 From: Elias Ohm Date: Thu, 4 Oct 2018 14:08:52 +0200 Subject: [PATCH 2/3] added cast to disable warnings... --- src/dpiObject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dpiObject.c b/src/dpiObject.c index d9c651c7..ae193441 100644 --- a/src/dpiObject.c +++ b/src/dpiObject.c @@ -252,7 +252,7 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) { asBytes = &data->value.asBytes; dpiOci__rawPtr(obj->env->handle, *value->asOciraw, - &asBytes->ptr); + (void **)&asBytes->ptr); dpiOci__rawSize(obj->env->handle, *value->asOciraw, &asBytes->length); asBytes->encoding = NULL; From c7acf2867aafa08642a7d194f7579157a5929055 Mon Sep 17 00:00:00 2001 From: Elias Ohm Date: Thu, 4 Oct 2018 23:02:18 +0200 Subject: [PATCH 3/3] add raw attribute to UDT_OBJECTDATATYPE and test 1205 --- test/TestDataTypes.c | 17 ++++++++++++++--- test/sql/SetupTest.sql | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/test/TestDataTypes.c b/test/TestDataTypes.c index 9b88ad7e..0702a324 100644 --- a/test/TestDataTypes.c +++ b/test/TestDataTypes.c @@ -1086,11 +1086,11 @@ int dpiTest_1205_verifyObjectAttributes(dpiTestCase *testCase, const char *insertSql = "insert into TestObjectDataTypes values (:1)"; const char *selectSql = "select ObjectCol from TestObjectDataTypes"; const char *objectName = "UDT_OBJECTDATATYPES"; - dpiData data, *objColValue, attrValues[13]; - uint32_t i, bufferRowIndex, numAttrs = 13; + dpiData data, *objColValue, attrValues[14]; + uint32_t i, bufferRowIndex, numAttrs = 14; dpiNativeTypeNum nativeTypeNum; dpiObjectAttrInfo attrInfo; - dpiObjectAttr *attrs[13]; + dpiObjectAttr *attrs[14]; dpiQueryInfo queryInfo; dpiObjectType *objType; dpiObject *obj; @@ -1162,6 +1162,10 @@ int dpiTest_1205_verifyObjectAttributes(dpiTestCase *testCase, if (dpiObject_setAttributeValue(obj, attrs[12], DPI_NATIVE_TYPE_INT64, &data) < 0) return dpiTestCase_setFailedFromError(testCase); + dpiData_setBytes(&data, "RawData", strlen("RawData")); + if (dpiObject_setAttributeValue(obj, attrs[13], DPI_NATIVE_TYPE_BYTES, + &data) < 0) + return dpiTestCase_setFailedFromError(testCase); // insert data if (dpiConn_prepareStmt(conn, 0, insertSql, strlen(insertSql), NULL, 0, @@ -1246,6 +1250,8 @@ int dpiTest_1205_verifyObjectAttributes(dpiTestCase *testCase, if (dpiTest__compareTimestamps(testCase, dpiData_getTimestamp(&data), dpiData_getTimestamp(&attrValues[8])) < 0) return DPI_FAILURE; + //work with german dbtimzone here + dpiData_setTimestamp(&data, 2017, 6, 1, 4, 2, 1, 0, 0, 0); if (dpiTest__compareTimestamps(testCase, dpiData_getTimestamp(&data), dpiData_getTimestamp(&attrValues[9])) < 0) return DPI_FAILURE; @@ -1258,6 +1264,11 @@ int dpiTest_1205_verifyObjectAttributes(dpiTestCase *testCase, if (dpiTestCase_expectDoubleEqual(testCase, dpiData_getInt64(&attrValues[12]), 123) < 0) return dpiTestCase_setFailedFromError(testCase); + if (dpiTestCase_expectStringEqual(testCase, + dpiData_getBytes(&attrValues[13])->ptr, + dpiData_getBytes(&attrValues[13])->length, "RawData", + strlen("RawData")) < 0) + return dpiTestCase_setFailedFromError(testCase); // cleanup for (i = 0; i < numAttrs; i++) { diff --git a/test/sql/SetupTest.sql b/test/sql/SetupTest.sql index da8ca938..500352b7 100644 --- a/test/sql/SetupTest.sql +++ b/test/sql/SetupTest.sql @@ -119,7 +119,8 @@ create type &main_user..udt_ObjectDataTypes as object ( TimestampLTZCol timestamp with local time zone, BinaryFltCol binary_float, BinaryDoubleCol binary_double, - SignedIntCol integer + SignedIntCol integer, + RawCol raw(16) ); /