static void _php_ibase_free_trans(zend_resource *rsrc) /* {{{ */ { ibase_trans *trans = (ibase_trans *)rsrc->ptr; unsigned short i; IBDEBUG("Cleaning up transaction resource..."); if (trans->handle != 0) { IBDEBUG("Rolling back unhandled transaction..."); if (isc_rollback_transaction(IB_STATUS, &trans->handle)) { _php_ibase_error(); } } /* now remove this transaction from all the connection-transaction lists */ for (i = 0; i < trans->link_cnt; ++i) { if (trans->db_link[i] != NULL) { ibase_tr_list **l; for (l = &trans->db_link[i]->tr_list; *l != NULL; l = &(*l)->next) { if ( (*l)->trans == trans) { ibase_tr_list *p = *l; *l = p->next; efree(p); break; } } } } efree(trans); }
/* Fill ib_link and trans with the correct database link and transaction. */ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */ zval *link_id, ibase_db_link **ib_link, ibase_trans **trans) { IBDEBUG("Transaction or database link?"); if (Z_RES_P(link_id)->type == le_trans) { /* Transaction resource: make sure it refers to one link only, then fetch it; database link is stored in ib_trans->db_link[]. */ IBDEBUG("Type is le_trans"); ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans); if ((*trans)->link_cnt > 1) { _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections." ); return; } *ib_link = (*trans)->db_link[0]; return; }
static void _php_ibase_commit_link(ibase_db_link *link) /* {{{ */ { unsigned short i = 0, j; ibase_tr_list *l; ibase_event *e; IBDEBUG("Checking transactions to close..."); for (l = link->tr_list; l != NULL; ++i) { ibase_tr_list *p = l; if (p->trans != 0) { if (i == 0) { if (p->trans->handle != 0) { IBDEBUG("Committing default transaction..."); if (isc_commit_transaction(IB_STATUS, &p->trans->handle)) { _php_ibase_error(); } } efree(p->trans); /* default transaction is not a registered resource: clean up */ } else { if (p->trans->handle != 0) { /* non-default trans might have been rolled back by other call of this dtor */ IBDEBUG("Rolling back other transactions..."); if (isc_rollback_transaction(IB_STATUS, &p->trans->handle)) { _php_ibase_error(); } } /* set this link pointer to NULL in the transaction */ for (j = 0; j < p->trans->link_cnt; ++j) { if (p->trans->db_link[j] == link) { p->trans->db_link[j] = NULL; break; } } } } l = l->next; efree(p); } link->tr_list = NULL; for (e = link->event_head; e; e = e->event_next) { _php_ibase_free_event(e); e->link = NULL; } }
static void _php_ibase_close_link(zend_resource *rsrc) /* {{{ */ { ibase_db_link *link = (ibase_db_link *) rsrc->ptr; _php_ibase_commit_link(link); if (link->handle != 0) { IBDEBUG("Closing normal link..."); isc_detach_database(IB_STATUS, &link->handle); } IBG(num_links)--; efree(link); }
/* Fill ib_link and trans with the correct database link and transaction. */ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */ zval *link_id, ibase_db_link **ib_link, ibase_trans **trans) { IBDEBUG("Transaction or database link?"); if (Z_RES_P(link_id)->type == le_trans) { /* Transaction resource: make sure it refers to one link only, then fetch it; database link is stored in ib_trans->db_link[]. */ IBDEBUG("Type is le_trans"); *trans = (ibase_trans *)zend_fetch_resource_ex(link_id, LE_TRANS, le_trans); if ((*trans)->link_cnt > 1) { _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections." ); return; } *ib_link = (*trans)->db_link[0]; return; } IBDEBUG("Type is le_[p]link or id not found"); /* Database link resource, use default transaction. */ *trans = NULL; *ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_id, LE_LINK, le_link, le_plink); }