/* {{{ php_oci_column_hash_dtor()
Column hash destructor */
void php_oci_column_hash_dtor(void *data)
-{
+{
php_oci_out_column *column = (php_oci_out_column *) data;
TSRMLS_FETCH();
php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
TSRMLS_FETCH();
- if (descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
+ if (descriptor && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
}
+ data = NULL;
+}
+/* }}} */
+
+/* {{{ php_oci_descriptor_delete_from_hash()
+ Delete descriptor from the hash */
+int php_oci_descriptor_delete_from_hash(void *data, void *id TSRMLS_DC)
+{
+ php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
+ int *desc_id = (int *) id;
+
+ if (descriptor && desc_id && descriptor->id == *desc_id) {
+ return 1;
+ }
+ return 0;
}
/* }}} */
Commit connection */
int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC)
{
- if (connection->descriptors) {
- zend_hash_apply(connection->descriptors,(apply_func_t) php_oci_descriptor_flush_hash_dtor TSRMLS_CC);
- }
-
connection->errcode = PHP_OCI_CALL(OCITransCommit, (connection->svc, connection->err, (ub4) 0));
connection->needs_commit = 0;
connection = (php_oci_connection *)le->ptr;
if (connection->used_this_request) {
- php_oci_connection_rollback(connection TSRMLS_CC);
-
if (connection->descriptors) {
zend_hash_destroy(connection->descriptors);
efree(connection->descriptors);
connection->descriptors = NULL;
}
+ php_oci_connection_rollback(connection TSRMLS_CC);
+
if (OCI_G(persistent_timeout) > 0) {
connection->idle_expiry = timestamp + OCI_G(persistent_timeout);
}
PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
if (connection->descriptors) {
- zend_hash_apply(connection->descriptors,(apply_func_t) php_oci_descriptor_flush_hash_dtor TSRMLS_CC);
+ zend_hash_destroy(connection->descriptors);
+ efree(connection->descriptors);
+ connection->descriptors = NULL;
}
if (php_oci_connection_rollback(connection TSRMLS_CC)) {
PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
if (connection->descriptors) {
- zend_hash_apply(connection->descriptors,(apply_func_t) php_oci_descriptor_flush_hash_dtor TSRMLS_CC);
+ zend_hash_destroy(connection->descriptors);
+ efree(connection->descriptors);
+ connection->descriptors = NULL;
}
if (php_oci_connection_commit(connection TSRMLS_CC)) {
break;
}
- descriptor = emalloc(sizeof(php_oci_descriptor));
+ descriptor = ecalloc(1, sizeof(php_oci_descriptor));
descriptor->type = type;
OCI_G(errcode) = PHP_OCI_CALL(OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0));
/* add Lobs & Files to hash. we'll flush them at the end */
if (!connection->descriptors) {
ALLOC_HASHTABLE(connection->descriptors);
- zend_hash_init(connection->descriptors, 13, NULL, php_oci_descriptor_flush_hash_dtor, 0);
+ zend_hash_init(connection->descriptors, 0, NULL, php_oci_descriptor_flush_hash_dtor, 0);
}
zend_hash_next_index_insert(connection->descriptors,&descriptor,sizeof(php_oci_descriptor *),NULL);
Close LOB descriptor and free associated resources */
void php_oci_lob_free (php_oci_descriptor *descriptor TSRMLS_DC)
{
+
+ if (!descriptor || !descriptor->connection) {
+ return;
+ }
+
+ if (descriptor->connection->descriptors) {
+ /* delete descriptor from the hash */
+ zend_hash_apply_with_argument(descriptor->connection->descriptors, php_oci_descriptor_delete_from_hash, (void *)&descriptor->id TSRMLS_CC);
+ }
+
/* 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 TSRMLS_CC);
} /* }}} */
/* {{{ php_oci_lob_is_equal()
- Compare to LOB descriptors and figure out if they are pointing to the same LOB */
+ Compare two LOB descriptors and figure out if they are pointing to the same LOB */
int php_oci_lob_is_equal (php_oci_descriptor *descriptor_first, php_oci_descriptor *descriptor_second, boolean *result TSRMLS_DC)
{
php_oci_connection *connection = descriptor_first->connection;
void php_oci_define_hash_dtor (void *data);
void php_oci_bind_hash_dtor (void *data);
void php_oci_descriptor_flush_hash_dtor (void *data);
+int php_oci_descriptor_delete_from_hash(void *data, void *id TSRMLS_DC);
sb4 php_oci_error (OCIError *, sword TSRMLS_DC);
sb4 php_oci_fetch_errmsg(OCIError *, text ** TSRMLS_DC);
--- /dev/null
+--TEST--
+commit connection after destroying the descriptor
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+unset($blob);
+unset($statement);
+
+oci_commit($c);
+
+$ora_sql = "SELECT blob FROM ".$schema.$table_name." ";
+$statement = oci_parse($c,$ora_sql);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($row = oci_fetch_assoc($statement));
+unset($row['BLOB']);
+
+oci_commit($c);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECTF--
+array(1) {
+ ["BLOB"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+Done