#include "dpiImpl.h"
static int dpiObjectType__init(dpiObjectType *objType, void *handle,
uint32_t handleType, dpiError *error);
int dpiObjectType__allocate(dpiConn *conn, void *handle, uint32_t handleType,
dpiObjectType **objType, dpiError *error)
{
dpiObjectType *tempObjType;
*objType = NULL;
if (dpiGen__allocate(DPI_HTYPE_OBJECT_TYPE, conn->env,
(void**) &tempObjType, error) < 0)
return DPI_FAILURE;
dpiGen__setRefCount(conn, error, 1);
tempObjType->conn = conn;
if (dpiObjectType__init(tempObjType, handle, handleType, error) < 0) {
dpiObjectType__free(tempObjType, error);
return DPI_FAILURE;
}
*objType = tempObjType;
return DPI_SUCCESS;
}
static int dpiObjectType__check(dpiObjectType *objType, const char *fnName,
dpiError *error)
{
if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, fnName,
error) < 0)
return DPI_FAILURE;
return dpiConn__checkConnected(objType->conn, error);
}
static int dpiObjectType__describe(dpiObjectType *objType,
void *describeHandle, dpiError *error)
{
void *collectionParam, *param;
uint16_t typeCode;
if (dpiOci__describeAny(objType->conn, objType->tdo, 0, DPI_OCI_OTYPE_PTR,
describeHandle, error) < 0)
return DPI_FAILURE;
if (dpiOci__attrGet(describeHandle, DPI_OCI_HTYPE_DESCRIBE, ¶m, 0,
DPI_OCI_ATTR_PARAM, "get top level parameter", error) < 0)
return DPI_FAILURE;
if (dpiOci__attrGet(param, DPI_OCI_DTYPE_PARAM, &typeCode, 0,
DPI_OCI_ATTR_TYPECODE, "get type code", error) < 0)
return DPI_FAILURE;
objType->typeCode = typeCode;
if (dpiUtils__getAttrStringWithDup("get schema", param,
DPI_OCI_DTYPE_PARAM, DPI_OCI_ATTR_SCHEMA_NAME, &objType->schema,
&objType->schemaLength, error) < 0)
return DPI_FAILURE;
if (dpiUtils__getAttrStringWithDup("get name", param, DPI_OCI_DTYPE_PARAM,
DPI_OCI_ATTR_NAME, &objType->name, &objType->nameLength,
error) < 0)
return DPI_FAILURE;
if (dpiUtils__getAttrStringWithDup("get package name", param,
DPI_OCI_DTYPE_PARAM, DPI_OCI_ATTR_PACKAGE_NAME,
&objType->packageName, &objType->packageNameLength, error) < 0)
return DPI_FAILURE;
if (dpiOci__attrGet(param, DPI_OCI_DTYPE_PARAM,
(void*) &objType->numAttributes, 0, DPI_OCI_ATTR_NUM_TYPE_ATTRS,
"get number of attributes", error) < 0)
return DPI_FAILURE;
if (typeCode == DPI_SQLT_NCO) {
objType->isCollection = 1;
if (dpiOci__attrGet(param, DPI_OCI_DTYPE_PARAM, &collectionParam, 0,
DPI_OCI_ATTR_COLLECTION_ELEMENT, "get collection descriptor",
error) < 0)
return DPI_FAILURE;
if (dpiOracleType__populateTypeInfo(objType->conn, collectionParam,
DPI_OCI_DTYPE_PARAM, &objType->elementTypeInfo, error) < 0)
return DPI_FAILURE;
}
return DPI_SUCCESS;
}
void dpiObjectType__free(dpiObjectType *objType, dpiError *error)
{
if (objType->conn) {
dpiGen__setRefCount(objType->conn, error, -1);
objType->conn = NULL;
}
if (objType->elementTypeInfo.objectType) {
dpiGen__setRefCount(objType->elementTypeInfo.objectType, error, -1);
objType->elementTypeInfo.objectType = NULL;
}
if (objType->schema) {
dpiUtils__freeMemory((void*) objType->schema);
objType->schema = NULL;
}
if (objType->name) {
dpiUtils__freeMemory((void*) objType->name);
objType->name = NULL;
}
if (objType->packageName) {
dpiUtils__freeMemory((void*) objType->packageName);
objType->packageName = NULL;
}
dpiUtils__freeMemory(objType);
}
static int dpiObjectType__init(dpiObjectType *objType, void *handle,
uint32_t handleType, dpiError *error)
{
void *describeHandle, *tdoReference;
if (dpiOci__attrGet(handle, handleType, (void*) &tdoReference, 0,
DPI_OCI_ATTR_REF_TDO, "get TDO reference", error) < 0)
return DPI_FAILURE;
if (dpiOci__objectPin(objType->env->handle, tdoReference, &objType->tdo,
error) < 0)
return DPI_FAILURE;
if (dpiOci__handleAlloc(objType->env->handle, &describeHandle,
DPI_OCI_HTYPE_DESCRIBE, "allocate describe handle", error) < 0)
return DPI_FAILURE;
if (dpiObjectType__describe(objType, describeHandle, error) < 0) {
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return DPI_FAILURE;
}
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return DPI_SUCCESS;
}
int dpiObjectType__isXmlType(dpiObjectType *objType)
{
static const char *schema = "SYS", *name = "XMLTYPE";
size_t schemaLength, nameLength;
schemaLength = strlen(schema);
nameLength = strlen(name);
return (objType->schemaLength == schemaLength &&
strncmp(objType->schema, schema, schemaLength) == 0 &&
objType->nameLength == nameLength &&
strncmp(objType->name, name, nameLength) == 0);
}
int dpiObjectType_addRef(dpiObjectType *objType)
{
return dpiGen__addRef(objType, DPI_HTYPE_OBJECT_TYPE, __func__);
}
int dpiObjectType_createObject(dpiObjectType *objType, dpiObject **obj)
{
dpiError error;
int status;
if (dpiObjectType__check(objType, __func__, &error) < 0)
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(objType, obj)
status = dpiObject__allocate(objType, NULL, NULL, NULL, obj, &error);
return dpiGen__endPublicFn(objType, status, &error);
}
int dpiObjectType_getAttributes(dpiObjectType *objType, uint16_t numAttributes,
dpiObjectAttr **attributes)
{
void *topLevelParam, *attrListParam, *attrParam, *describeHandle;
dpiError error;
uint16_t i;
if (dpiObjectType__check(objType, __func__, &error) < 0)
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(objType, attributes)
if (numAttributes < objType->numAttributes) {
dpiError__set(&error, "get attributes", DPI_ERR_ARRAY_SIZE_TOO_SMALL,
numAttributes);
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
}
if (numAttributes == 0)
return dpiGen__endPublicFn(objType, DPI_SUCCESS, &error);
if (dpiOci__handleAlloc(objType->env->handle, &describeHandle,
DPI_OCI_HTYPE_DESCRIBE, "allocate describe handle", &error) < 0)
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
if (dpiOci__describeAny(objType->conn, objType->tdo, 0, DPI_OCI_OTYPE_PTR,
describeHandle, &error) < 0) {
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
}
if (dpiOci__attrGet(describeHandle, DPI_OCI_HTYPE_DESCRIBE, &topLevelParam,
0, DPI_OCI_ATTR_PARAM, "get top level param", &error) < 0) {
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
}
if (dpiOci__attrGet(topLevelParam, DPI_OCI_DTYPE_PARAM,
(void*) &attrListParam, 0, DPI_OCI_ATTR_LIST_TYPE_ATTRS,
"get attr list param", &error) < 0) {
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
}
for (i = 0; i < objType->numAttributes; i++) {
if (dpiOci__paramGet(attrListParam, DPI_OCI_DTYPE_PARAM, &attrParam,
(uint32_t) i + 1, "get attribute param", &error) < 0) {
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
}
if (dpiObjectAttr__allocate(objType, attrParam, &attributes[i],
&error) < 0) {
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
}
}
dpiOci__handleFree(describeHandle, DPI_OCI_HTYPE_DESCRIBE);
return dpiGen__endPublicFn(objType, DPI_SUCCESS, &error);
}
int dpiObjectType_getInfo(dpiObjectType *objType, dpiObjectTypeInfo *info)
{
dpiError error;
if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, __func__,
&error) < 0)
return dpiGen__endPublicFn(objType, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(objType, info)
info->name = objType->name;
info->nameLength = objType->nameLength;
info->packageName = objType->packageName;
info->packageNameLength = objType->packageNameLength;
info->schema = objType->schema;
info->schemaLength = objType->schemaLength;
info->isCollection = objType->isCollection;
info->numAttributes = objType->numAttributes;
if (objType->env->context->dpiMinorVersion > 1) {
info->elementTypeInfo = objType->elementTypeInfo;
} else if (objType->env->context->dpiMinorVersion == 1) {
memcpy(&info->elementTypeInfo, &objType->elementTypeInfo,
sizeof(dpiDataTypeInfo__v51));
} else {
memcpy(&info->elementTypeInfo, &objType->elementTypeInfo,
sizeof(dpiDataTypeInfo__v50));
}
return dpiGen__endPublicFn(objType, DPI_SUCCESS, &error);
}
int dpiObjectType_release(dpiObjectType *objType)
{
return dpiGen__release(objType, DPI_HTYPE_OBJECT_TYPE, __func__);
}