#include "dpiImpl.h"
int dpiObject__closeHelper(dpiObject *obj, int checkError, dpiError *error);
int dpiObject__allocate(dpiObjectType *objType, void *instance,
void *indicator, dpiObject *dependsOnObj, dpiObject **obj,
dpiError *error)
{
dpiObject *tempObj;
if (dpiGen__allocate(DPI_HTYPE_OBJECT, objType->env, (void**) &tempObj,
error) < 0)
return DPI_FAILURE;
dpiGen__setRefCount(objType, error, 1);
tempObj->type = objType;
tempObj->instance = instance;
tempObj->indicator = indicator;
if (dependsOnObj) {
dpiGen__setRefCount(dependsOnObj, error, 1);
tempObj->dependsOnObj = dependsOnObj;
}
if (!instance) {
if (dpiOci__objectNew(tempObj, error) < 0) {
dpiObject__free(tempObj, error);
return DPI_FAILURE;
}
if (dpiOci__objectGetInd(tempObj, error) < 0) {
dpiObject__free(tempObj, error);
return DPI_FAILURE;
}
}
if (tempObj->instance && !dependsOnObj) {
if (dpiHandleList__addHandle(objType->conn->objects, tempObj,
&tempObj->openSlotNum, error) < 0) {
dpiObject__free(tempObj, error);
return DPI_FAILURE;
}
}
*obj = tempObj;
return DPI_SUCCESS;
}
static int dpiObject__check(dpiObject *obj, const char *fnName,
dpiError *error)
{
if (dpiGen__startPublicFn(obj, DPI_HTYPE_OBJECT, fnName, error) < 0)
return DPI_FAILURE;
return dpiConn__checkConnected(obj->type->conn, error);
}
static int dpiObject__checkIsCollection(dpiObject *obj, const char *fnName,
dpiError *error)
{
if (dpiObject__check(obj, fnName, error) < 0)
return DPI_FAILURE;
if (!obj->type->isCollection)
return dpiError__set(error, "check collection", DPI_ERR_NOT_COLLECTION,
obj->type->schemaLength, obj->type->schema,
obj->type->nameLength, obj->type->name);
return DPI_SUCCESS;
}
static void dpiObject__clearOracleValue(dpiObject *obj, dpiError *error,
dpiOracleDataBuffer *buffer, dpiLob *lob,
dpiOracleTypeNum oracleTypeNum)
{
switch (oracleTypeNum) {
case DPI_ORACLE_TYPE_CHAR:
case DPI_ORACLE_TYPE_NCHAR:
case DPI_ORACLE_TYPE_VARCHAR:
case DPI_ORACLE_TYPE_NVARCHAR:
if (buffer->asString)
dpiOci__stringResize(obj->env->handle, &buffer->asString, 0,
error);
break;
case DPI_ORACLE_TYPE_RAW:
if (buffer->asRawData)
dpiOci__rawResize(obj->env->handle, &buffer->asRawData, 0,
error);
break;
case DPI_ORACLE_TYPE_TIMESTAMP:
if (buffer->asTimestamp)
dpiOci__descriptorFree(buffer->asTimestamp,
DPI_OCI_DTYPE_TIMESTAMP);
break;
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
if (buffer->asTimestamp)
dpiOci__descriptorFree(buffer->asTimestamp,
DPI_OCI_DTYPE_TIMESTAMP_TZ);
break;
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
if (buffer->asTimestamp)
dpiOci__descriptorFree(buffer->asTimestamp,
DPI_OCI_DTYPE_TIMESTAMP_LTZ);
break;
case DPI_ORACLE_TYPE_CLOB:
case DPI_ORACLE_TYPE_NCLOB:
case DPI_ORACLE_TYPE_BLOB:
case DPI_ORACLE_TYPE_BFILE:
if (lob)
dpiGen__setRefCount(lob, error, -1);
break;
default:
break;
};
}
int dpiObject__close(dpiObject *obj, int checkError, dpiError *error)
{
int closing;
if (obj->env->threaded)
dpiMutex__acquire(obj->env->mutex);
closing = obj->closing;
obj->closing = 1;
if (obj->env->threaded)
dpiMutex__release(obj->env->mutex);
if (closing)
return DPI_SUCCESS;
if (obj->instance && !obj->dependsOnObj) {
if (dpiObject__closeHelper(obj, checkError, error) < 0) {
if (obj->env->threaded)
dpiMutex__acquire(obj->env->mutex);
obj->closing = 0;
if (obj->env->threaded)
dpiMutex__release(obj->env->mutex);
return DPI_FAILURE;
}
}
return DPI_SUCCESS;
}
int dpiObject__closeHelper(dpiObject *obj, int checkError, dpiError *error)
{
if (dpiOci__objectFree(obj->env->handle, obj->instance, checkError,
error) < 0)
return DPI_FAILURE;
obj->instance = NULL;
if (obj->freeIndicator && dpiOci__objectFree(obj->env->handle,
obj->indicator, checkError, error) < 0)
return DPI_FAILURE;
obj->indicator = NULL;
if (!obj->type->conn->closing)
dpiHandleList__removeHandle(obj->type->conn->objects,
obj->openSlotNum);
return DPI_SUCCESS;
}
void dpiObject__free(dpiObject *obj, dpiError *error)
{
dpiObject__close(obj, 0, error);
if (obj->type) {
dpiGen__setRefCount(obj->type, error, -1);
obj->type = NULL;
}
if (obj->dependsOnObj) {
dpiGen__setRefCount(obj->dependsOnObj, error, -1);
obj->dependsOnObj = NULL;
}
dpiUtils__freeMemory(obj);
}
static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error,
const dpiDataTypeInfo *typeInfo, dpiOracleData *value,
int16_t *indicator, dpiNativeTypeNum nativeTypeNum, dpiData *data)
{
dpiOracleTypeNum valueOracleTypeNum;
dpiBytes *asBytes;
if (*indicator == DPI_OCI_IND_NULL) {
data->isNull = 1;
return DPI_SUCCESS;
}
data->isNull = 0;
valueOracleTypeNum = typeInfo->oracleTypeNum;
switch (valueOracleTypeNum) {
case DPI_ORACLE_TYPE_CHAR:
case DPI_ORACLE_TYPE_NCHAR:
case DPI_ORACLE_TYPE_VARCHAR:
case DPI_ORACLE_TYPE_NVARCHAR:
if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
asBytes = &data->value.asBytes;
dpiOci__stringPtr(obj->env->handle, *value->asString,
&asBytes->ptr);
dpiOci__stringSize(obj->env->handle, *value->asString,
&asBytes->length);
if (valueOracleTypeNum == DPI_ORACLE_TYPE_NCHAR ||
valueOracleTypeNum == DPI_ORACLE_TYPE_NVARCHAR)
asBytes->encoding = obj->env->nencoding;
else asBytes->encoding = obj->env->encoding;
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->asRawData,
(void**) &asBytes->ptr);
dpiOci__rawSize(obj->env->handle, *value->asRawData,
&asBytes->length);
asBytes->encoding = NULL;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NATIVE_INT:
if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) {
data->value.asInt64 = *value->asInt32;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
if (nativeTypeNum == DPI_NATIVE_TYPE_FLOAT) {
data->value.asFloat = *value->asFloat;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) {
data->value.asDouble = *value->asDouble;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NUMBER:
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
return dpiDataBuffer__fromOracleNumberAsDouble(&data->value,
error, value->asNumber);
else if (nativeTypeNum == DPI_NATIVE_TYPE_INT64)
return dpiDataBuffer__fromOracleNumberAsInteger(&data->value,
error, value->asNumber);
else if (nativeTypeNum == DPI_NATIVE_TYPE_UINT64)
return dpiDataBuffer__fromOracleNumberAsUnsignedInteger(
&data->value, error, value->asNumber);
else if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES)
return dpiDataBuffer__fromOracleNumberAsText(&data->value,
obj->env, error, value->asNumber);
break;
case DPI_ORACLE_TYPE_DATE:
if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP)
return dpiDataBuffer__fromOracleDate(&data->value,
value->asDate);
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
return dpiDataBuffer__fromOracleDateAsDouble(&data->value,
obj->env, error, value->asDate);
break;
case DPI_ORACLE_TYPE_TIMESTAMP:
if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP)
return dpiDataBuffer__fromOracleTimestamp(&data->value,
obj->env, error, *value->asTimestamp, 0);
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
return dpiDataBuffer__fromOracleTimestampAsDouble(&data->value,
valueOracleTypeNum, obj->env, error,
*value->asTimestamp);
break;
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP)
return dpiDataBuffer__fromOracleTimestamp(&data->value,
obj->env, error, *value->asTimestamp, 1);
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
return dpiDataBuffer__fromOracleTimestampAsDouble(&data->value,
valueOracleTypeNum, obj->env, error,
*value->asTimestamp);
break;
case DPI_ORACLE_TYPE_OBJECT:
if (typeInfo->objectType &&
nativeTypeNum == DPI_NATIVE_TYPE_OBJECT) {
void *instance = (typeInfo->objectType->isCollection) ?
*value->asCollection : value->asRaw;
dpiObject *tempObj;
if (dpiObject__allocate(typeInfo->objectType, instance,
indicator, obj, &tempObj, error) < 0)
return DPI_FAILURE;
data->value.asObject = tempObj;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_BOOLEAN:
if (nativeTypeNum == DPI_NATIVE_TYPE_BOOLEAN) {
data->value.asBoolean = *(value->asBoolean);
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_CLOB:
case DPI_ORACLE_TYPE_NCLOB:
case DPI_ORACLE_TYPE_BLOB:
case DPI_ORACLE_TYPE_BFILE:
if (nativeTypeNum == DPI_NATIVE_TYPE_LOB) {
const dpiOracleType *lobType;
void *tempLocator;
dpiLob *tempLob;
lobType = dpiOracleType__getFromNum(typeInfo->oracleTypeNum,
error);
if (dpiLob__allocate(obj->type->conn, lobType, &tempLob,
error) < 0)
return DPI_FAILURE;
tempLocator = tempLob->locator;
tempLob->locator = *(value->asLobLocator);
if (dpiOci__lobLocatorAssign(tempLob, &tempLocator,
error) < 0) {
tempLob->locator = tempLocator;
dpiLob__free(tempLob, error);
return DPI_FAILURE;
}
tempLob->locator = tempLocator;
data->value.asLOB = tempLob;
return DPI_SUCCESS;
}
break;
default:
break;
};
return dpiError__set(error, "from Oracle value",
DPI_ERR_UNHANDLED_CONVERSION, valueOracleTypeNum, nativeTypeNum);
}
static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error,
const dpiDataTypeInfo *dataTypeInfo, dpiOracleDataBuffer *buffer,
dpiLob **lob, void **ociValue, int16_t *valueIndicator,
void **objectIndicator, dpiNativeTypeNum nativeTypeNum, dpiData *data)
{
dpiOracleTypeNum valueOracleTypeNum;
uint32_t handleType;
dpiObject *otherObj;
dpiBytes *bytes;
*objectIndicator = NULL;
if (data->isNull) {
*ociValue = NULL;
*valueIndicator = DPI_OCI_IND_NULL;
buffer->asRaw = NULL;
return DPI_SUCCESS;
}
*valueIndicator = DPI_OCI_IND_NOTNULL;
valueOracleTypeNum = dataTypeInfo->oracleTypeNum;
switch (valueOracleTypeNum) {
case DPI_ORACLE_TYPE_CHAR:
case DPI_ORACLE_TYPE_NCHAR:
case DPI_ORACLE_TYPE_VARCHAR:
case DPI_ORACLE_TYPE_NVARCHAR:
buffer->asString = NULL;
if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
bytes = &data->value.asBytes;
if (dpiOci__stringAssignText(obj->env->handle, bytes->ptr,
bytes->length, &buffer->asString, error) < 0)
return DPI_FAILURE;
*ociValue = buffer->asString;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_RAW:
buffer->asRawData = NULL;
if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
bytes = &data->value.asBytes;
if (dpiOci__rawAssignBytes(obj->env->handle, bytes->ptr,
bytes->length, &buffer->asRawData, error) < 0)
return DPI_FAILURE;
*ociValue = buffer->asRawData;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NATIVE_INT:
if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) {
buffer->asInt32 = (int32_t) data->value.asInt64;
*ociValue = &buffer->asInt32;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NUMBER:
*ociValue = &buffer->asNumber;
if (nativeTypeNum == DPI_NATIVE_TYPE_INT64)
return dpiDataBuffer__toOracleNumberFromInteger(&data->value,
error, &buffer->asNumber);
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
return dpiDataBuffer__toOracleNumberFromDouble(&data->value,
error, &buffer->asNumber);
if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES)
return dpiDataBuffer__toOracleNumberFromText(&data->value,
obj->env, error, &buffer->asNumber);
break;
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
if (nativeTypeNum == DPI_NATIVE_TYPE_FLOAT) {
buffer->asFloat = data->value.asFloat;
*ociValue = &buffer->asFloat;
return DPI_SUCCESS;
} else if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) {
buffer->asFloat = (float) data->value.asDouble;
*ociValue = &buffer->asFloat;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) {
buffer->asDouble = data->value.asDouble;
*ociValue = &buffer->asDouble;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_DATE:
*ociValue = &buffer->asDate;
if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP)
return dpiDataBuffer__toOracleDate(&data->value,
&buffer->asDate);
if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
return dpiDataBuffer__toOracleDateFromDouble(&data->value,
obj->env, error, &buffer->asDate);
break;
case DPI_ORACLE_TYPE_TIMESTAMP:
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
buffer->asTimestamp = NULL;
if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP ||
nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) {
if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_LTZ) {
handleType = DPI_OCI_DTYPE_TIMESTAMP_LTZ;
} else if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP) {
handleType = DPI_OCI_DTYPE_TIMESTAMP;
} else {
handleType = DPI_OCI_DTYPE_TIMESTAMP_TZ;
}
if (dpiOci__descriptorAlloc(obj->env->handle,
&buffer->asTimestamp, handleType, "allocate timestamp",
error) < 0)
return DPI_FAILURE;
*ociValue = buffer->asTimestamp;
if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP)
return dpiDataBuffer__toOracleTimestamp(&data->value,
obj->env, error, buffer->asTimestamp,
(valueOracleTypeNum != DPI_ORACLE_TYPE_TIMESTAMP));
return dpiDataBuffer__toOracleTimestampFromDouble(&data->value,
valueOracleTypeNum, obj->env, error,
buffer->asTimestamp);
}
break;
case DPI_ORACLE_TYPE_OBJECT:
otherObj = data->value.asObject;
if (nativeTypeNum == DPI_NATIVE_TYPE_OBJECT) {
if (otherObj->type->tdo != dataTypeInfo->objectType->tdo)
return dpiError__set(error, "check type",
DPI_ERR_WRONG_TYPE, otherObj->type->schemaLength,
otherObj->type->schema, otherObj->type->nameLength,
otherObj->type->name,
dataTypeInfo->objectType->schemaLength,
dataTypeInfo->objectType->schema,
dataTypeInfo->objectType->nameLength,
dataTypeInfo->objectType->name);
*ociValue = otherObj->instance;
*objectIndicator = otherObj->indicator;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_BOOLEAN:
if (nativeTypeNum == DPI_NATIVE_TYPE_BOOLEAN) {
buffer->asBoolean = data->value.asBoolean;
*ociValue = &buffer->asBoolean;
return DPI_SUCCESS;
}
break;
case DPI_ORACLE_TYPE_CLOB:
case DPI_ORACLE_TYPE_NCLOB:
case DPI_ORACLE_TYPE_BLOB:
case DPI_ORACLE_TYPE_BFILE:
buffer->asLobLocator = NULL;
if (nativeTypeNum == DPI_NATIVE_TYPE_LOB) {
*ociValue = data->value.asLOB->locator;
return DPI_SUCCESS;
} else if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
const dpiOracleType *lobType;
lobType = dpiOracleType__getFromNum(valueOracleTypeNum, error);
if (dpiLob__allocate(obj->type->conn, lobType, lob, error) < 0)
return DPI_FAILURE;
bytes = &data->value.asBytes;
if (dpiLob__setFromBytes(*lob, bytes->ptr, bytes->length,
error) < 0)
return DPI_FAILURE;
buffer->asLobLocator = (*lob)->locator;
*ociValue = (*lob)->locator;
return DPI_SUCCESS;
}
break;
default:
break;
}
return dpiError__set(error, "to Oracle value",
DPI_ERR_UNHANDLED_CONVERSION, valueOracleTypeNum, nativeTypeNum);
}
int dpiObject_addRef(dpiObject *obj)
{
return dpiGen__addRef(obj, DPI_HTYPE_OBJECT, __func__);
}
int dpiObject_appendElement(dpiObject *obj, dpiNativeTypeNum nativeTypeNum,
dpiData *data)
{
dpiOracleDataBuffer valueBuffer;
int16_t scalarValueIndicator;
dpiLob *lob = NULL;
void *indicator;
dpiError error;
void *ociValue;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, data)
status = dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo,
&valueBuffer, &lob, &ociValue, &scalarValueIndicator,
(void**) &indicator, nativeTypeNum, data);
if (status == DPI_SUCCESS) {
if (!indicator)
indicator = &scalarValueIndicator;
status = dpiOci__collAppend(obj->type->conn, ociValue, indicator,
obj->instance, &error);
}
dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob,
obj->type->elementTypeInfo.oracleTypeNum);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_copy(dpiObject *obj, dpiObject **copiedObj)
{
dpiObject *tempObj;
dpiError error;
if (dpiObject__check(obj, __func__, &error) < 0)
return DPI_FAILURE;
DPI_CHECK_PTR_NOT_NULL(obj, copiedObj)
if (dpiObject__allocate(obj->type, NULL, NULL, NULL, &tempObj, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
if (dpiOci__objectCopy(tempObj, obj->instance, obj->indicator,
&error) < 0) {
dpiObject__free(tempObj, &error);
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
}
*copiedObj = tempObj;
return dpiGen__endPublicFn(obj, DPI_SUCCESS, &error);
}
int dpiObject_deleteElementByIndex(dpiObject *obj, int32_t index)
{
dpiError error;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
status = dpiOci__tableDelete(obj, index, &error);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getAttributeValue(dpiObject *obj, dpiObjectAttr *attr,
dpiNativeTypeNum nativeTypeNum, dpiData *data)
{
int16_t scalarValueIndicator;
void *valueIndicator, *tdo;
dpiOracleData value;
dpiError error;
int status;
if (dpiObject__check(obj, __func__, &error) < 0)
return DPI_FAILURE;
DPI_CHECK_PTR_NOT_NULL(obj, data)
if (dpiGen__checkHandle(attr, DPI_HTYPE_OBJECT_ATTR, "get attribute value",
&error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
if (attr->belongsToType->tdo != obj->type->tdo) {
dpiError__set(&error, "get attribute value", DPI_ERR_WRONG_ATTR,
attr->nameLength, attr->name, obj->type->schemaLength,
obj->type->schema, obj->type->nameLength, obj->type->name);
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
}
if (dpiOci__objectGetAttr(obj, attr, &scalarValueIndicator,
&valueIndicator, &value.asRaw, &tdo, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
if (!valueIndicator)
valueIndicator = &scalarValueIndicator;
if (!attr->typeInfo.oracleTypeNum) {
dpiError__set(&error, "get attribute value",
DPI_ERR_UNHANDLED_DATA_TYPE, attr->typeInfo.ociTypeCode);
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
}
status = dpiObject__fromOracleValue(obj, &error, &attr->typeInfo, &value,
(int16_t*) valueIndicator, nativeTypeNum, data);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getElementExistsByIndex(dpiObject *obj, int32_t index,
int *exists)
{
dpiError error;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, exists)
status = dpiOci__tableExists(obj, index, exists, &error);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getElementValueByIndex(dpiObject *obj, int32_t index,
dpiNativeTypeNum nativeTypeNum, dpiData *data)
{
dpiOracleData value;
int exists, status;
void *indicator;
dpiError error;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, data)
if (dpiOci__collGetElem(obj->type->conn, obj->instance, index, &exists,
&value.asRaw, &indicator, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
if (!exists) {
dpiError__set(&error, "get element value", DPI_ERR_INVALID_INDEX,
index);
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
}
status = dpiObject__fromOracleValue(obj, &error,
&obj->type->elementTypeInfo, &value, (int16_t*) indicator,
nativeTypeNum, data);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getFirstIndex(dpiObject *obj, int32_t *index, int *exists)
{
dpiError error;
int32_t size;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, index)
DPI_CHECK_PTR_NOT_NULL(obj, exists)
if (dpiOci__tableSize(obj, &size, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
*exists = (size != 0);
if (*exists)
status = dpiOci__tableFirst(obj, index, &error);
else status = DPI_SUCCESS;
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getLastIndex(dpiObject *obj, int32_t *index, int *exists)
{
dpiError error;
int32_t size;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, index)
DPI_CHECK_PTR_NOT_NULL(obj, exists)
if (dpiOci__tableSize(obj, &size, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
*exists = (size != 0);
if (*exists)
status = dpiOci__tableLast(obj, index, &error);
else status = DPI_SUCCESS;
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getNextIndex(dpiObject *obj, int32_t index, int32_t *nextIndex,
int *exists)
{
dpiError error;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, nextIndex)
DPI_CHECK_PTR_NOT_NULL(obj, exists)
status = dpiOci__tableNext(obj, index, nextIndex, exists, &error);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getPrevIndex(dpiObject *obj, int32_t index, int32_t *prevIndex,
int *exists)
{
dpiError error;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, prevIndex)
DPI_CHECK_PTR_NOT_NULL(obj, exists)
status = dpiOci__tablePrev(obj, index, prevIndex, exists, &error);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_getSize(dpiObject *obj, int32_t *size)
{
dpiError error;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, size)
status = dpiOci__collSize(obj->type->conn, obj->instance, size, &error);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_release(dpiObject *obj)
{
return dpiGen__release(obj, DPI_HTYPE_OBJECT, __func__);
}
int dpiObject_setAttributeValue(dpiObject *obj, dpiObjectAttr *attr,
dpiNativeTypeNum nativeTypeNum, dpiData *data)
{
void *valueIndicator, *ociValue;
dpiOracleDataBuffer valueBuffer;
int16_t scalarValueIndicator;
dpiLob *lob = NULL;
dpiError error;
int status;
if (dpiObject__check(obj, __func__, &error) < 0)
return DPI_FAILURE;
DPI_CHECK_PTR_NOT_NULL(obj, data)
if (dpiGen__checkHandle(attr, DPI_HTYPE_OBJECT_ATTR, "set attribute value",
&error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
if (attr->belongsToType->tdo != obj->type->tdo) {
dpiError__set(&error, "set attribute value", DPI_ERR_WRONG_ATTR,
attr->nameLength, attr->name, obj->type->schemaLength,
obj->type->schema, obj->type->nameLength, obj->type->name);
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
}
if (!attr->typeInfo.oracleTypeNum) {
dpiError__set(&error, "get attribute value",
DPI_ERR_UNHANDLED_DATA_TYPE, attr->typeInfo.ociTypeCode);
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
}
status = dpiObject__toOracleValue(obj, &error, &attr->typeInfo,
&valueBuffer, &lob, &ociValue, &scalarValueIndicator,
&valueIndicator, nativeTypeNum, data);
if (status == DPI_SUCCESS)
status = dpiOci__objectSetAttr(obj, attr, scalarValueIndicator,
valueIndicator, ociValue, &error);
dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob,
attr->typeInfo.oracleTypeNum);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_setElementValueByIndex(dpiObject *obj, int32_t index,
dpiNativeTypeNum nativeTypeNum, dpiData *data)
{
dpiOracleDataBuffer valueBuffer;
int16_t scalarValueIndicator;
dpiLob *lob = NULL;
void *indicator;
dpiError error;
void *ociValue;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(obj, data)
status = dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo,
&valueBuffer, &lob, &ociValue, &scalarValueIndicator,
(void**) &indicator, nativeTypeNum, data);
if (status == DPI_SUCCESS) {
if (!indicator)
indicator = &scalarValueIndicator;
status = dpiOci__collAssignElem(obj->type->conn, index, ociValue,
indicator, obj->instance, &error);
}
dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob,
obj->type->elementTypeInfo.oracleTypeNum);
return dpiGen__endPublicFn(obj, status, &error);
}
int dpiObject_trim(dpiObject *obj, uint32_t numToTrim)
{
dpiError error;
int status;
if (dpiObject__checkIsCollection(obj, __func__, &error) < 0)
return dpiGen__endPublicFn(obj, DPI_FAILURE, &error);
status = dpiOci__collTrim(obj->type->conn, numToTrim, obj->instance,
&error);
return dpiGen__endPublicFn(obj, status, &error);
}