/* {{{ php_oci_lob_free() Close LOB descriptor and free associated resources */ void php_oci_lob_free (php_oci_descriptor *descriptor) { if (!descriptor || !descriptor->connection) { return; } if (descriptor->connection->descriptors) { /* delete descriptor from the hash */ zend_hash_index_del(descriptor->connection->descriptors, descriptor->index); if (zend_hash_num_elements(descriptor->connection->descriptors) == 0) { descriptor->connection->descriptor_count = 0; } else { if (descriptor->index + 1 == descriptor->connection->descriptor_count) { /* If the descriptor being freed is the end-most one * allocated, then the descriptor_count is reduced so * a future descriptor can reuse the hash table index. * This can prevent the hash index range increasing in * the common case that each descriptor is * allocated/used/freed before another descriptor is * needed. However it is possible that a script frees * descriptors in arbitrary order which would prevent * descriptor_count ever being reduced to zero until * zend_hash_num_elements() returns 0. */ descriptor->connection->descriptor_count--; } } } /* flushing Lobs & Files with buffering enabled */ if ((descriptor->type == OCI_DTYPE_FILE || descriptor->type == OCI_DTYPE_LOB) && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED) { php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE); } if (descriptor->type == OCI_DTYPE_LOB) { php_oci_temp_lob_close(descriptor); } PHP_OCI_CALL(OCIDescriptorFree, (descriptor->descriptor, descriptor->type)); zend_list_delete(descriptor->connection->id); efree(descriptor); }
/* {{{ php_oci_collection_create() Create and return connection handle */ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, char *tdo, int tdo_len, char *schema, int schema_len TSRMLS_DC) { dvoid *dschp1 = NULL; dvoid *parmp1; dvoid *parmp2; php_oci_collection *collection; collection = emalloc(sizeof(php_oci_collection)); collection->connection = connection; collection->collection = NULL; zend_list_addref(collection->connection->rsrc_id); /* get type handle by name */ PHP_OCI_CALL_RETURN(connection->errcode, OCITypeByName, ( connection->env, connection->err, connection->svc, (text *) schema, (ub4) schema_len, (text *) tdo, (ub4) tdo_len, (CONST text *) 0, (ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_ALL, &(collection->tdo) ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* allocate describe handle */ PHP_OCI_CALL_RETURN(connection->errcode, OCIHandleAlloc, (connection->env, (dvoid **) &dschp1, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0)); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* describe TDO */ PHP_OCI_CALL_RETURN(connection->errcode, OCIDescribeAny, ( connection->svc, connection->err, (dvoid *) collection->tdo, (ub4) 0, OCI_OTYPE_PTR, (ub1) OCI_DEFAULT, (ub1) OCI_PTYPE_TYPE, dschp1 ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* get first parameter handle */ PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, ((dvoid *) dschp1, (ub4) OCI_HTYPE_DESCRIBE, (dvoid *)&parmp1, (ub4 *)0, (ub4)OCI_ATTR_PARAM, connection->err)); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* get the collection type code of the attribute */ PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, ( (dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM, (dvoid*) &(collection->coll_typecode), (ub4 *) 0, (ub4) OCI_ATTR_COLLECTION_TYPECODE, connection->err ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } switch(collection->coll_typecode) { case OCI_TYPECODE_TABLE: case OCI_TYPECODE_VARRAY: /* get collection element handle */ PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, ( (dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM, (dvoid*) &parmp2, (ub4 *) 0, (ub4) OCI_ATTR_COLLECTION_ELEMENT, connection->err ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* get REF of the TDO for the type */ PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, ( (dvoid*) parmp2, (ub4) OCI_DTYPE_PARAM, (dvoid*) &(collection->elem_ref), (ub4 *) 0, (ub4) OCI_ATTR_REF_TDO, connection->err ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* get the TDO (only header) */ PHP_OCI_CALL_RETURN(connection->errcode, OCITypeByRef, ( connection->env, connection->err, collection->elem_ref, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, &(collection->element_type) ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* get typecode */ PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, ( (dvoid*) parmp2, (ub4) OCI_DTYPE_PARAM, (dvoid*) &(collection->element_typecode), (ub4 *) 0, (ub4) OCI_ATTR_TYPECODE, connection->err ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } break; /* we only support VARRAYs and TABLEs */ default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown collection type %d", collection->coll_typecode); break; } /* Create object to hold return table */ PHP_OCI_CALL_RETURN(connection->errcode, OCIObjectNew, ( connection->env, connection->err, connection->svc, OCI_TYPECODE_TABLE, collection->tdo, (dvoid *)0, OCI_DURATION_DEFAULT, TRUE, (dvoid **) &(collection->collection) ) ); if (connection->errcode != OCI_SUCCESS) { goto CLEANUP; } /* free the describe handle (Bug #44113) */ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) dschp1, OCI_HTYPE_DESCRIBE)); PHP_OCI_REGISTER_RESOURCE(collection, le_collection); return collection; CLEANUP: if (dschp1) { /* free the describe handle (Bug #44113) */ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) dschp1, OCI_HTYPE_DESCRIBE)); } php_oci_error(connection->err, connection->errcode TSRMLS_CC); php_oci_collection_close(collection TSRMLS_CC); return NULL; } /* }}} */