abies           Tue Aug  5 19:40:30 2003 EDT

  Modified files:              
    /php-src/ext/interbase      interbase.c 
  Log:
  Changed ibase_trans() to allow multi-DB transactions with distinct 
  trans_args for each connection.
  
  
Index: php-src/ext/interbase/interbase.c
diff -u php-src/ext/interbase/interbase.c:1.114 php-src/ext/interbase/interbase.c:1.115
--- php-src/ext/interbase/interbase.c:1.114     Tue Aug  5 12:30:47 2003
+++ php-src/ext/interbase/interbase.c   Tue Aug  5 19:40:30 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: interbase.c,v 1.114 2003/08/05 16:30:47 sniper Exp $ */
+/* $Id: interbase.c,v 1.115 2003/08/05 23:40:30 abies Exp $ */
 
 
 /* TODO: Arrays, roles?
@@ -670,7 +670,7 @@
 
        php_info_print_table_start();
        php_info_print_table_row(2, "Interbase Support", "enabled");
-       php_info_print_table_row(2, "Revision", "$Revision: 1.114 $");
+       php_info_print_table_row(2, "Revision", "$Revision: 1.115 $");
 #ifdef COMPILE_DL_INTERBASE
        php_info_print_table_row(2, "Dynamic Module", "yes");
 #endif
@@ -974,7 +974,7 @@
    Close an InterBase connection */
 PHP_FUNCTION(ibase_close)
 {
-       zval **link_arg;
+       zval **link_arg = NULL;
        ibase_db_link *ib_link;
        int link_id;
        
@@ -1006,7 +1006,7 @@
    Drop an InterBase database */
 PHP_FUNCTION(ibase_drop_db)
 {
-       zval **link_arg;
+       zval **link_arg = NULL;
        ibase_db_link *ib_link;
        int link_id;
        
@@ -1576,98 +1576,120 @@
 }
 /* }}} */
 
-/* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier]])
-   Start transaction */
+/* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier [, ... 
], int trans_args [, resource link_identifier [, ... ]] [, ...]]])
+   Start a transaction over one or several databases */
+
+#define TPB_MAX_SIZE (8*sizeof(char))
+
 PHP_FUNCTION(ibase_trans)
 {
-       zval ***args;
-       char tpb[20];
-       long trans_argl = 0;
-       int tpb_len = 0, argn, link_cnt, link_id[19], i;
-       ibase_db_link *ib_link[19];
+       unsigned i, argn, link_cnt = 0, tpb_len = 0;
+       char last_tpb[TPB_MAX_SIZE];
+       ibase_db_link **ib_link = NULL;
        ibase_trans *ib_trans;
-
-       ISC_TEB *teb;
        isc_tr_handle tr_handle = NULL;
+       ISC_STATUS result;
        
        RESET_ERRMSG;
 
        argn = ZEND_NUM_ARGS();
-       if (argn < 0) {
-               WRONG_PARAM_COUNT;
-       }
 
-       if (argn) {
-               /* the number of databases this transaction connects to */
-               link_cnt = argn-1;
+       /* (1+argn) is an upper bound for the number of links this trans connects to */
+       ib_link = (ibase_db_link**)do_alloca(sizeof(ibase_db_link*) * (1+argn));
+       
+       if (argn > 0) {
+               long trans_argl = 0;
+               char *tpb;
+               ISC_TEB *teb;
+               zval ***args = (zval ***)do_alloca(sizeof(zval **) * argn);
 
-               args = (zval ***) emalloc(sizeof(zval **) * argn);
                if (zend_get_parameters_array_ex(argn, args) == FAILURE) {
-                       efree(args);
+                       free_alloca(args);
+                       free_alloca(ib_link);
                        RETURN_FALSE;
                }
 
-               /* Handle all database links. */
-               for (i = argn-1; i > 0 && Z_TYPE_PP(args[i]) == IS_RESOURCE; --i) {
-                       ZEND_FETCH_RESOURCE2(ib_link[i-1], ibase_db_link *, args[i], 
-1, "InterBase link", le_link, le_plink);
-                       link_id[i-1] = Z_LVAL_PP(args[i]);
-               }
+               teb = (ISC_TEB*)do_alloca(sizeof(ISC_TEB) * argn);
+               tpb = (char*)do_alloca(TPB_MAX_SIZE * argn);
 
-               /* First argument is transaction parameters */
-               convert_to_long_ex(args[0]);
-               trans_argl = Z_LVAL_PP(args[0]);
+               /* enumerate all the arguments: assume every non-resource argument 
+                  specifies modifiers for the link ids that follow it */
+               for (i = 0; i < argn; ++i) {
+                       
+                       if (Z_TYPE_PP(args[i]) == IS_RESOURCE) {
+                               
+                               ZEND_FETCH_RESOURCE2(ib_link[link_cnt], ibase_db_link 
*, args[i], -1, "InterBase link", le_link, le_plink);
+       
+                               /* copy the most recent modifier string into tbp[] */
+                               memcpy(&tpb[TPB_MAX_SIZE * link_cnt], last_tpb, 
TPB_MAX_SIZE);
 
-               efree(args);
-       }
+                               /* add a database handle to the TEB with the most 
recently specified set of modifiers */
+                               teb[link_cnt].db_ptr = &ib_link[link_cnt]->link;
+                               teb[link_cnt].tpb_len = tpb_len;
+                               teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt];
+                               
+                               ++link_cnt;
+                               
+                       } else {
+                               
+                               tpb_len = 0;
 
-       if (argn < 2) {
-               link_cnt = 1;
-               ZEND_FETCH_RESOURCE2(ib_link[0], ibase_db_link *, NULL, 
IBG(default_link), "InterBase link", le_link, le_plink);
-       }
+                               convert_to_long_ex(args[i]);
+                               trans_argl = Z_LVAL_PP(args[i]);
 
-       if (trans_argl) {
-               tpb[tpb_len++] = isc_tpb_version3;
-               /* tpbp = tpb; */
-               /* access mode */
-               if (trans_argl & PHP_IBASE_READ) { /* READ ONLY TRANSACTION */
-                       tpb[tpb_len++] = isc_tpb_read;
-               } else {
-                       tpb[tpb_len++] = isc_tpb_write;  /* default  access mode */
-               }
-               /* isolation level */
-               if (trans_argl & PHP_IBASE_COMMITTED) {
-                       tpb[tpb_len++] = isc_tpb_read_committed;
-                       if (trans_argl & PHP_IBASE_REC_VERSION) {
-                               tpb[tpb_len++] = isc_tpb_rec_version;
-                       } else {
-                               tpb[tpb_len++] = isc_tpb_no_rec_version; /* default in 
read_committed  */ 
-                       }       
-               } else if (trans_argl & PHP_IBASE_CONSISTENCY) {
-                       tpb[tpb_len++] = isc_tpb_consistency;
-               } else {
-                       tpb[tpb_len++] = isc_tpb_concurrency;   /* default isolation 
level */ 
-               }
-               
-               /* lock resolution */
-               if (trans_argl & PHP_IBASE_NOWAIT) {
-                       tpb[tpb_len++] = isc_tpb_nowait;
-               } else {
-                       tpb[tpb_len++] = isc_tpb_wait;  /* default lock resolution */
+                               if (trans_argl) {
+                                       last_tpb[tpb_len++] = isc_tpb_version3;
+
+                                       /* access mode */
+                                       if (trans_argl & PHP_IBASE_READ) { /* READ 
ONLY TRANSACTION */
+                                               last_tpb[tpb_len++] = isc_tpb_read;
+                                       } else {
+                                               last_tpb[tpb_len++] = isc_tpb_write;  
/* default access mode */
+                                       }
+
+                                       /* isolation level */
+                                       if (trans_argl & PHP_IBASE_COMMITTED) {
+                                               last_tpb[tpb_len++] = 
isc_tpb_read_committed;
+                                               if (trans_argl & 
PHP_IBASE_REC_VERSION) {
+                                                       last_tpb[tpb_len++] = 
isc_tpb_rec_version;
+                                               } else {
+                                                       last_tpb[tpb_len++] = 
isc_tpb_no_rec_version; /* default in read_committed  */ 
+                                               }       
+                                       } else if (trans_argl & PHP_IBASE_CONSISTENCY) 
{
+                                               last_tpb[tpb_len++] = 
isc_tpb_consistency;
+                                       } else {
+                                               last_tpb[tpb_len++] = 
isc_tpb_concurrency;   /* default isolation level */ 
+                                       }
+                                       
+                                       /* lock resolution */
+                                       if (trans_argl & PHP_IBASE_NOWAIT) {
+                                               last_tpb[tpb_len++] = isc_tpb_nowait;
+                                       } else {
+                                               last_tpb[tpb_len++] = isc_tpb_wait;  
/* default lock resolution */
+                                       }
+                               }
+                       }
+               }       
+                                       
+               if (link_cnt > 0) {
+                       result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, 
teb);
                }
+
+               free_alloca(args);
+               free_alloca(tpb);
+               free_alloca(teb);
        }
 
-       /* allocate a TEB array */
-       teb = (ISC_TEB*) emalloc(sizeof(ISC_TEB) * link_cnt);
-       for (i = 0; i < link_cnt; ++i) {
-               teb[i].db_ptr = &ib_link[i]->link;
-               teb[i].tpb_len = tpb_len;
-               teb[i].tpb_ptr = tpb;
+       if (link_cnt == 0) {
+               link_cnt = 1;
+               ZEND_FETCH_RESOURCE2(ib_link[0], ibase_db_link *, NULL, 
IBG(default_link), "InterBase link", le_link, le_plink);
+               result = isc_start_transaction(IB_STATUS, &tr_handle, 1, 
&ib_link[0]->link, tpb_len, last_tpb);
        }
        
        /* start the transaction */
-       if (isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb)) {
+       if (result) {
                _php_ibase_error(TSRMLS_C);
-               efree(teb);
+               free_alloca(ib_link);
                RETURN_FALSE;
        }
 
@@ -1692,7 +1714,7 @@
                (*l)->trans = ib_trans;
                (*l)->next = NULL;
        }
-       efree(teb);
+       free_alloca(ib_link);
        ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
 }
 /* }}} */
@@ -1824,6 +1846,7 @@
        /* use stack to avoid leaks */
        args = (zval ***) do_alloca(sizeof(zval **) * ZEND_NUM_ARGS());
        if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
+               free_alloca(args);
                RETURN_FALSE;
        }
        
@@ -2459,6 +2482,7 @@
        /* use stack to avoid leaks */
        args = (zval ***) do_alloca(ZEND_NUM_ARGS() * sizeof(zval **));
        if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
+               free_alloca(args);
                RETURN_FALSE;
        }
 



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to