/* {{{ php_oci_lob_create() Create LOB descriptor and allocate all the resources needed */ php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long type TSRMLS_DC) { php_oci_descriptor *descriptor; switch (type) { case OCI_DTYPE_FILE: case OCI_DTYPE_LOB: case OCI_DTYPE_ROWID: /* these three are allowed */ break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown descriptor type %ld", type); return NULL; break; } descriptor = ecalloc(1, sizeof(php_oci_descriptor)); descriptor->type = type; descriptor->connection = connection; zend_list_addref(descriptor->connection->rsrc_id); PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0)); if (OCI_G(errcode) != OCI_SUCCESS) { OCI_G(errcode) = php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, OCI_G(errcode)); efree(descriptor); return NULL; } PHP_OCI_REGISTER_RESOURCE(descriptor, le_descriptor); descriptor->lob_current_position = 0; descriptor->lob_size = -1; /* we should set it to -1 to know, that it's just not initialized */ descriptor->buffering = PHP_OCI_LOB_BUFFER_DISABLED; /* buffering is off by default */ descriptor->charset_form = SQLCS_IMPLICIT; /* default value */ descriptor->charset_id = connection->charset; descriptor->is_open = 0; if (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE) { /* add Lobs & Files to hash. we'll flush them at the end */ if (!connection->descriptors) { ALLOC_HASHTABLE(connection->descriptors); zend_hash_init(connection->descriptors, 0, NULL, php_oci_descriptor_flush_hash_dtor, 0); connection->descriptor_count = 0; } descriptor->index = (connection->descriptor_count)++; if (connection->descriptor_count == LONG_MAX) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal descriptor counter has reached limit"); php_oci_connection_descriptors_free(connection TSRMLS_CC); return NULL; } zend_hash_index_update(connection->descriptors,descriptor->index,&descriptor,sizeof(php_oci_descriptor *),NULL); } return 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; } /* }}} */