thekid          Sun Jan 25 15:14:11 2004 EDT

  Modified files:              (Branch: PHP_4_3)
    /php-src/ext/sybase_ct      php_sybase_ct.c php_sybase_ct.h 
  Log:
  - MFH
  
http://cvs.php.net/diff.php/php-src/ext/sybase_ct/php_sybase_ct.c?r1=1.73.2.8&r2=1.73.2.9&ty=u
Index: php-src/ext/sybase_ct/php_sybase_ct.c
diff -u php-src/ext/sybase_ct/php_sybase_ct.c:1.73.2.8 
php-src/ext/sybase_ct/php_sybase_ct.c:1.73.2.9
--- php-src/ext/sybase_ct/php_sybase_ct.c:1.73.2.8      Thu Aug 28 16:29:13 2003
+++ php-src/ext/sybase_ct/php_sybase_ct.c       Sun Jan 25 15:14:05 2004
@@ -2,7 +2,7 @@
    +----------------------------------------------------------------------+
    | PHP Version 4                                                        |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2003 The PHP Group                                |
+   | Copyright (c) 1997-2004 The PHP Group                                |
    +----------------------------------------------------------------------+
    | This source file is subject to version 3.0 of the PHP license,       |
    | that is bundled with this package in the file LICENSE, and is        |
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_sybase_ct.c,v 1.73.2.8 2003/08/28 20:29:13 andrey Exp $ */
+/* $Id: php_sybase_ct.c,v 1.73.2.9 2004/01/25 20:14:05 thekid Exp $ */
 
 
 #ifdef HAVE_CONFIG_H
@@ -38,53 +38,54 @@
 #if HAVE_SYBASE_CT
 
 function_entry sybase_functions[] = {
-       PHP_FE(sybase_connect,                          NULL)
-       PHP_FE(sybase_pconnect,                         NULL)
-       PHP_FE(sybase_close,                            NULL)
-       PHP_FE(sybase_select_db,                        NULL)
-       PHP_FE(sybase_query,                            NULL)
-       PHP_FE(sybase_unbuffered_query,                 NULL)
-       PHP_FE(sybase_free_result,                      NULL)
-       PHP_FE(sybase_get_last_message,                 NULL)
-       PHP_FE(sybase_num_rows,                         NULL)
-       PHP_FE(sybase_num_fields,                       NULL)
-       PHP_FE(sybase_fetch_row,                        NULL)
-       PHP_FE(sybase_fetch_array,                      NULL)
-       PHP_FE(sybase_fetch_assoc,                      NULL)
-       PHP_FE(sybase_fetch_object,                     NULL)
-       PHP_FE(sybase_data_seek,                        NULL)
-       PHP_FE(sybase_fetch_field,                      NULL)
-       PHP_FE(sybase_field_seek,                       NULL)
-       PHP_FE(sybase_result,                           NULL)
-       PHP_FE(sybase_affected_rows,                    NULL)
-       PHP_FE(sybase_min_client_severity,              NULL)
-       PHP_FE(sybase_min_server_severity,              NULL)
-       PHP_FE(sybase_set_message_handler,              NULL)
-       PHP_FE(sybase_deadlock_retry_count,             NULL)
-
-       PHP_FALIAS(mssql_connect,                       sybase_connect,                
 NULL)
-       PHP_FALIAS(mssql_pconnect,                      sybase_pconnect,               
 NULL)
-       PHP_FALIAS(mssql_close,                         sybase_close,                  
 NULL)
-       PHP_FALIAS(mssql_select_db,                     sybase_select_db,              
 NULL)
-       PHP_FALIAS(mssql_query,                         sybase_query,                  
 NULL)
-       PHP_FALIAS(mssql_unbuffered_query,              sybase_unbuffered_query,       
 NULL)
-       PHP_FALIAS(mssql_free_result,                   sybase_free_result,            
 NULL)
-       PHP_FALIAS(mssql_get_last_message,              sybase_get_last_message,       
 NULL)
-       PHP_FALIAS(mssql_num_rows,                      sybase_num_rows,               
 NULL)
-       PHP_FALIAS(mssql_num_fields,                    sybase_num_fields,             
 NULL)
-       PHP_FALIAS(mssql_fetch_row,                     sybase_fetch_row,              
 NULL)
-       PHP_FALIAS(mssql_fetch_array,                   sybase_fetch_array,            
 NULL)
-       PHP_FALIAS(mssql_fetch_assoc,                   sybase_fetch_assoc,            
 NULL)
-       PHP_FALIAS(mssql_fetch_object,                  sybase_fetch_object,           
 NULL)
-       PHP_FALIAS(mssql_data_seek,                     sybase_data_seek,              
 NULL)
-       PHP_FALIAS(mssql_fetch_field,                   sybase_fetch_field,            
 NULL)
-       PHP_FALIAS(mssql_field_seek,                    sybase_field_seek,             
 NULL)
-       PHP_FALIAS(mssql_result,                        sybase_result,                 
 NULL)
-       PHP_FALIAS(mssql_affected_rows,                 sybase_affected_rows,          
 NULL)
-       PHP_FALIAS(mssql_min_client_severity,           sybase_min_client_severity,    
 NULL)
-       PHP_FALIAS(mssql_min_server_severity,           sybase_min_server_severity,    
 NULL)
-       PHP_FALIAS(mssql_set_message_handler,           sybase_set_message_handler,    
 NULL)
-       PHP_FALIAS(mssql_deadlock_retry_count,          sybase_deadlock_retry_count,   
 NULL)
+       PHP_FE(sybase_connect, NULL)
+       PHP_FE(sybase_pconnect, NULL)
+       PHP_FE(sybase_close, NULL)
+       PHP_FE(sybase_select_db, NULL)
+       PHP_FE(sybase_query, NULL)
+       PHP_FE(sybase_unbuffered_query, NULL)
+       PHP_FE(sybase_free_result, NULL)
+       PHP_FE(sybase_get_last_message, NULL)
+       PHP_FE(sybase_num_rows, NULL)
+       PHP_FE(sybase_num_fields, NULL)
+       PHP_FE(sybase_fetch_row, NULL)
+       PHP_FE(sybase_fetch_array, NULL)
+       PHP_FE(sybase_fetch_assoc, NULL)
+       PHP_FE(sybase_fetch_object, NULL)
+       PHP_FE(sybase_data_seek, NULL)
+       PHP_FE(sybase_fetch_field, NULL)
+       PHP_FE(sybase_field_seek, NULL)
+       PHP_FE(sybase_result, NULL)
+       PHP_FE(sybase_affected_rows, NULL)
+       PHP_FE(sybase_min_client_severity, NULL)
+       PHP_FE(sybase_min_server_severity, NULL)
+       PHP_FE(sybase_set_message_handler, NULL)
+       PHP_FE(sybase_deadlock_retry_count, NULL)
+
+       PHP_FALIAS(mssql_connect, sybase_connect, NULL)
+       PHP_FALIAS(mssql_pconnect, sybase_pconnect, NULL)
+       PHP_FALIAS(mssql_close, sybase_close, NULL)
+       PHP_FALIAS(mssql_select_db, sybase_select_db, NULL)
+       PHP_FALIAS(mssql_query, sybase_query, NULL)
+       PHP_FALIAS(mssql_unbuffered_query, sybase_unbuffered_query, NULL)
+       PHP_FALIAS(mssql_free_result, sybase_free_result, NULL)
+       PHP_FALIAS(mssql_get_last_message, sybase_get_last_message, NULL)
+       PHP_FALIAS(mssql_num_rows, sybase_num_rows, NULL)
+       PHP_FALIAS(mssql_num_fields, sybase_num_fields, NULL)
+       PHP_FALIAS(mssql_fetch_row, sybase_fetch_row, NULL)
+       PHP_FALIAS(mssql_fetch_array, sybase_fetch_array, NULL)
+       PHP_FALIAS(mssql_fetch_assoc, sybase_fetch_assoc, NULL)
+       PHP_FALIAS(mssql_fetch_object, sybase_fetch_object, NULL)
+       PHP_FALIAS(mssql_data_seek, sybase_data_seek, NULL)
+       PHP_FALIAS(mssql_fetch_field, sybase_fetch_field, NULL)
+       PHP_FALIAS(mssql_field_seek, sybase_field_seek, NULL)
+       PHP_FALIAS(mssql_result, sybase_result, NULL)
+       PHP_FALIAS(mssql_affected_rows, sybase_affected_rows, NULL)
+       PHP_FALIAS(mssql_min_client_severity,   sybase_min_client_severity, NULL)
+       PHP_FALIAS(mssql_min_server_severity, sybase_min_server_severity, NULL)
+       PHP_FALIAS(mssql_set_message_handler, sybase_set_message_handler, NULL)
+       PHP_FALIAS(mssql_deadlock_retry_count, sybase_deadlock_retry_count, NULL)
+
        {NULL, NULL, NULL}
 };
 
@@ -156,6 +157,10 @@
        CS_INT con_status;
 
        sybase_ptr->valid = 0;
+       if (sybase_ptr->callback_name != NULL) {
+               zval_ptr_dtor(&sybase_ptr->callback_name);
+               sybase_ptr->callback_name= NULL;
+       }
 
        zend_hash_apply(&EG(regular_list), (apply_func_t) _clean_invalid_results 
TSRMLS_CC);
 
@@ -233,60 +238,80 @@
        return CS_SUCCEED;
 }
 
-
-static CS_RETCODE CS_PUBLIC _server_message_handler(CS_CONTEXT *context, 
CS_CONNECTION *connection, CS_SERVERMSG *srvmsg)
+static int _call_message_handler(zval *callback_name, CS_SERVERMSG *srvmsg TSRMLS_DC)
 {
-       zval *retval = NULL;
-       zval severity, msgnumber, state, line, text;
-       zval *ptrs[5]= {&msgnumber, &severity, &state, &line, &text};
-       zval **args[5]= {&ptrs[0], &ptrs[1], &ptrs[2], &ptrs[3], &ptrs[4]};
-       int  handled= 0;
+       int handled = 0;
 
-       TSRMLS_FETCH();
-
-       if (srvmsg->severity >= SybCtG(min_server_severity)) {
-               if (SybCtG(callback_name) != NULL) {
-                       INIT_ZVAL(msgnumber);
-                       INIT_ZVAL(severity);
-                       INIT_ZVAL(state);
-                       INIT_ZVAL(line);
-                       INIT_ZVAL(text);
-       
-                       ZVAL_LONG(&msgnumber, srvmsg->msgnumber);
-                       ZVAL_LONG(&severity, srvmsg->severity);
-                       ZVAL_LONG(&state, srvmsg->state);
-                       ZVAL_LONG(&line, srvmsg->line);
-                       ZVAL_STRING(&text, srvmsg->text, 0);
+       if (callback_name) {
+               zval *retval = NULL;
+               zval severity, msgnumber, state, line, text;
+               zval *ptrs[5]= {&msgnumber, &severity, &state, &line, &text};
+               zval **args[5]= {&ptrs[0], &ptrs[1], &ptrs[2], &ptrs[3], &ptrs[4]};
+
+               INIT_ZVAL(msgnumber);
+               INIT_ZVAL(severity);
+               INIT_ZVAL(state);
+               INIT_ZVAL(line);
+               INIT_ZVAL(text);
+       
+               ZVAL_LONG(&msgnumber, srvmsg->msgnumber);
+               ZVAL_LONG(&severity, srvmsg->severity);
+               ZVAL_LONG(&state, srvmsg->state);
+               ZVAL_LONG(&line, srvmsg->line);
+               ZVAL_STRING(&text, srvmsg->text, 0);
                        
-                       if (call_user_function_ex(EG(function_table), NULL, 
SybCtG(callback_name), &retval, 5, args, 0, NULL TSRMLS_CC)== FAILURE) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  
Cannot call the messagehandler %s", Z_STRVAL_P(SybCtG(callback_name)));
-                       }
-                       if (retval) {
-                               handled= ((Z_TYPE_P(retval) != IS_BOOL) || 
(Z_BVAL_P(retval) != 0));
-                               zval_ptr_dtor(&retval);
-                       }
+               if (call_user_function_ex(EG(function_table), NULL, callback_name, 
&retval, 5, args, 0, NULL TSRMLS_CC) == FAILURE) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Cannot 
call the messagehandler %s", Z_STRVAL_P(callback_name));
                }
-
-               if (!handled) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Server 
message:  %s (severity %d, procedure %s)",
-                                       srvmsg->text, srvmsg->severity, 
((srvmsg->proclen>0) ? srvmsg->proc : "N/A"));
+               if (retval) {
+                       handled= ((Z_TYPE_P(retval) != IS_BOOL) || (Z_BVAL_P(retval) 
!= 0));
+                       zval_ptr_dtor(&retval);
                }
        }
+
+       return handled;
+}
+
+static CS_RETCODE CS_PUBLIC _server_message_handler(CS_CONTEXT *context, 
CS_CONNECTION *connection, CS_SERVERMSG *srvmsg)
+{
+       sybase_link *sybase;
+       int handled = 0;
+       TSRMLS_FETCH();
+
+       /* Remember the last server message in any case */
        STR_FREE(SybCtG(server_message));
        SybCtG(server_message) = estrdup(srvmsg->text);
 
+       /* Retrieve sybase link */
+       if (ct_con_props(connection, CS_GET, CS_USERDATA, &sybase, CS_SIZEOF(sybase), 
NULL) != CS_SUCCEED) {
+               sybase = NULL;
+       }
+
        /* If this is a deadlock message, set the connection's deadlock flag
         * so we will retry the request.  Sorry about the bare constant here,
         * but it's not defined anywhere and it's a "well-known" number.
         */
-       if (srvmsg->msgnumber == 1205) {
-               sybase_link *sybase;
+       if (sybase && (srvmsg->msgnumber == 1205)) {
+               sybase->deadlock = 1;
+       }
 
-               if (ct_con_props(connection, CS_GET, CS_USERDATA, &sybase, 
CS_SIZEOF(sybase), NULL)==CS_SUCCEED) {
-                       sybase->deadlock = 1;
-               } else {
-                       /* oh well */
-               }
+       /* Check mininum server severity level */
+       if (srvmsg->severity < SybCtG(min_server_severity)) {
+               return CS_SUCCEED;
+       }
+
+       /* Call global message handler */
+       handled = handled | _call_message_handler(SybCtG(callback_name), srvmsg 
TSRMLS_CC);
+
+       /* Call link specific message handler */
+       if (sybase) {
+               handled = handled | _call_message_handler(sybase->callback_name, 
srvmsg TSRMLS_CC);
+       }
+
+       /* Spit out a warning if neither of them has handled this message */
+       if (!handled) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Server message:  
%s (severity %d, procedure %s)",
+                               srvmsg->text, srvmsg->severity, ((srvmsg->proclen>0) ? 
srvmsg->proc : "N/A"));
        }
 
        return CS_SUCCEED;
@@ -294,19 +319,20 @@
 
 
 PHP_INI_BEGIN()
-       STD_PHP_INI_BOOLEAN("sybct.allow_persistent",   "1",    PHP_INI_SYSTEM,        
 OnUpdateInt,            allow_persistent,       zend_sybase_globals,    
sybase_globals)
-       STD_PHP_INI_ENTRY_EX("sybct.max_persistent",    "-1",   PHP_INI_SYSTEM,        
 OnUpdateInt,            max_persistent,         zend_sybase_globals,    
sybase_globals, display_link_numbers)
-       STD_PHP_INI_ENTRY_EX("sybct.max_links",         "-1",   PHP_INI_SYSTEM,        
 OnUpdateInt,            max_links,                      zend_sybase_globals,    
sybase_globals, display_link_numbers)
-       STD_PHP_INI_ENTRY("sybct.min_server_severity",  "10",   PHP_INI_ALL,           
 OnUpdateInt,            min_server_severity,    zend_sybase_globals,    
sybase_globals)
-       STD_PHP_INI_ENTRY("sybct.min_client_severity",  "10",   PHP_INI_ALL,           
 OnUpdateInt,            min_client_severity,    zend_sybase_globals,    
sybase_globals)
-       STD_PHP_INI_ENTRY("sybct.hostname",                     NULL,   PHP_INI_ALL,   
         OnUpdateString,         hostname,               zend_sybase_globals,          
  sybase_globals)
-       STD_PHP_INI_ENTRY_EX("sybct.deadlock_retry_count",      "-1",   PHP_INI_ALL,   
         OnUpdateInt,            deadlock_retry_count,   zend_sybase_globals,    
sybase_globals, display_link_numbers)
+       STD_PHP_INI_BOOLEAN("sybct.allow_persistent", "1", PHP_INI_SYSTEM, 
OnUpdateInt, allow_persistent, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY_EX("sybct.max_persistent", "-1", PHP_INI_SYSTEM, 
OnUpdateInt, max_persistent, zend_sybase_globals, sybase_globals, display_link_numbers)
+       STD_PHP_INI_ENTRY_EX("sybct.max_links", "-1", PHP_INI_SYSTEM, OnUpdateInt, 
max_links, zend_sybase_globals, sybase_globals, display_link_numbers)
+       STD_PHP_INI_ENTRY("sybct.min_server_severity", "10", PHP_INI_ALL, OnUpdateInt, 
min_server_severity, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY("sybct.min_client_severity", "10", PHP_INI_ALL, OnUpdateInt, 
min_client_severity, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY("sybct.login_timeout", "-1", PHP_INI_ALL, OnUpdateInt, 
login_timeout, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY("sybct.hostname", NULL, PHP_INI_ALL, OnUpdateString, 
hostname, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY_EX("sybct.deadlock_retry_count", "-1", PHP_INI_ALL, 
OnUpdateInt, deadlock_retry_count, zend_sybase_globals, sybase_globals, 
display_link_numbers)
 PHP_INI_END()
 
 
 static void php_sybase_init_globals(zend_sybase_globals *sybase_globals)
 {
-       long timeout;
+       long opt;
        TSRMLS_FETCH();
 
        if (cs_ctx_alloc(CTLIB_VERSION, &sybase_globals->context)!=CS_SUCCEED || 
ct_init(sybase_globals->context, CTLIB_VERSION)!=CS_SUCCEED) {
@@ -335,27 +361,29 @@
                }
        }
 
-       /* Set the login and command timeouts.  These are per-context and
-        * can't be set with ct_con_props(), so set them globally from
-        * their config values if requested.  The defaults are 1 minute
-        * for CS_LOGIN_TIMEOUT and CS_NO_LIMIT for CS_TIMEOUT.  The latter
-        * especially is fairly useless for web applications.
-        * Note that depite some noise in the documentation about using
+       /* Set the timeout, which is per context and can't be set with 
+        * ct_con_props(), so set it globally from the config value if 
+        * requested.  The default is CS_NO_LIMIT.
+        * 
+        * Note that despite some noise in the documentation about using
         * signals to implement timeouts, they are actually implemented
         * by using poll() or select() on Solaris and Linux.
         */
-       if (cfg_get_long("sybct.login_timeout", &timeout)==SUCCESS) {
-               CS_INT cs_login_timeout = timeout;
-               if (ct_config(sybase_globals->context, CS_SET, CS_LOGIN_TIMEOUT, 
&cs_login_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Unable 
to set login timeout");
+       if (cfg_get_long("sybct.timeout", &opt)==SUCCESS) {
+               CS_INT cs_timeout = opt;
+               if (ct_config(sybase_globals->context, CS_SET, CS_TIMEOUT, 
&cs_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Unable 
to update the timeout");
                }
        }
-       if (cfg_get_long("sybct.timeout", &timeout)==SUCCESS) {
-               CS_INT cs_timeout = timeout;
-               if (ct_config(sybase_globals->context, CS_SET, CS_TIMEOUT, 
&cs_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Unable 
to set timeout");
+
+       /* Set the packet size, which is also per context */
+       if (cfg_get_long("sybct.packet_size", &opt)==SUCCESS) {
+               CS_INT cs_packet_size = opt;
+               if (ct_config(sybase_globals->context, CS_SET, CS_PACKETSIZE, 
&cs_packet_size, CS_UNUSED, NULL)!=CS_SUCCEED) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Unable 
to update the packet size");
                }
        }
+
        sybase_globals->num_persistent=0;
        sybase_globals->callback_name = NULL;
 }
@@ -468,9 +496,29 @@
                }
        }
 
+       /* Set the login timeout. Actually, the login timeout is per context
+        * and not per connection, but we will update the context here to 
+        * allow for code such as the following:
+        * 
+        *   ini_set('sybct.login_timeout', $timeout);
+        *   sybase_connect(...)
+        * 
+        * Note that preceding calls to sybase_connect() will now use the 
+        * updated value and not the default one!
+        * 
+        * The default value for CS_LOGIN_TIMEOUT is 60 (1 minute).
+        */
+       if (SybCtG(login_timeout) != -1) {
+               CS_INT cs_login_timeout = SybCtG(login_timeout);
+               if (ct_config(SybCtG(context), CS_SET, CS_LOGIN_TIMEOUT, 
&cs_login_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Unable 
to update the login timeout");
+               }
+       }
+
        sybase->valid = 1;
        sybase->dead = 0;
        sybase->active_result_index = 0;
+       sybase->callback_name = NULL;
 
        /* create the link */
        if (ct_connect(sybase->connection, host, CS_NULLTERM)!=CS_SUCCEED) {
@@ -598,7 +646,6 @@
                        break;
        }
 
-
        if (!SybCtG(allow_persistent)) {
                persistent=0;
        }
@@ -610,12 +657,12 @@
                        list_entry new_le;
 
                        if (SybCtG(max_links)!=-1 && 
SybCtG(num_links)>=SybCtG(max_links)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  
Too many open links (%d)", SybCtG(num_links));
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  
Too many open links (%ld)", SybCtG(num_links));
                                efree(hashed_details);
                                RETURN_FALSE;
                        }
                        if (SybCtG(max_persistent)!=-1 && 
SybCtG(num_persistent)>=SybCtG(max_persistent)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  
Too many open persistent links (%d)", SybCtG(num_persistent));
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  
Too many open persistent links (%ld)", SybCtG(num_persistent));
                                efree(hashed_details);
                                RETURN_FALSE;
                        }
@@ -713,7 +760,7 @@
                        }
                }
                if (SybCtG(max_links)!=-1 && SybCtG(num_links)>=SybCtG(max_links)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Too many 
open links (%d)", SybCtG(num_links));
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Too many 
open links (%ld)", SybCtG(num_links));
                        efree(hashed_details);
                        RETURN_FALSE;
                }
@@ -935,9 +982,9 @@
 
 /* }}} */
 
-static void php_sybase_finish_results (sybase_result *result) 
+static int php_sybase_finish_results (sybase_result *result) 
 {
-       int i;
+       int i, fail;
        CS_RETCODE retcode;
        CS_INT restype;
        TSRMLS_FETCH();
@@ -962,6 +1009,7 @@
         * want to return a failure in this case because the application
         * won't be getting all the results it asked for.
         */
+       fail = 0;
        while ((retcode = ct_results(result->sybase_ptr->cmd, &restype))==CS_SUCCEED) {
                switch ((int) restype) {
                        case CS_CMD_SUCCEED:
@@ -969,8 +1017,9 @@
                                break;
 
                        case CS_CMD_FAIL:
-                               _free_sybase_result(result);
-                               result = NULL;
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  
Command failed, cancelling rest");
+                               ct_cancel(NULL, result->sybase_ptr->cmd, 
CS_CANCEL_ALL);
+                               fail = 1;
                                break;
 
                        case CS_COMPUTE_RESULT:
@@ -988,6 +1037,10 @@
                                ct_cancel(NULL, result->sybase_ptr->cmd, 
CS_CANCEL_ALL);
                                break;
                }
+
+               if (fail) {
+                       break;
+               }
        }
 
        switch (retcode) {
@@ -1012,8 +1065,11 @@
                default:
                        _free_sybase_result(result);
                        result = NULL;
+                       retcode = CS_FAIL;
                        break;
        }
+
+       return retcode;
 }
 
 static int php_sybase_fetch_result_row (sybase_result *result, int numrows) 
@@ -1057,7 +1113,14 @@
                                        case 1:
                                                convert_to_long(&result->data[i][j]);
                                                break;
-                                       case 2: 
+                                       case 2:
+                                               /* We also get numbers that are 
actually integers here due to the check on 
+                                                * precision against > 9 (ranges are 
-1E10 to -1E9 and 1E9 to 1E10). As we
+                                                * cannot be sure that they "fit" into 
MIN_LONG <= x <= MAX_LONG, we call
+                                                * convert_to_double() on them. This 
is a small performance penalty, but 
+                                                * ensures that "select 2147483648" 
will be a float and "select 2147483647"
+                                                * will be become an int.
+                                                */
                                                convert_to_double(&result->data[i][j]);
                                                break;
                                }
@@ -1070,7 +1133,7 @@
        
        switch (retcode) {
                case CS_END_DATA:
-                       php_sybase_finish_results(result);
+                       retcode = php_sybase_finish_results(result);
                        break;
                        
                case CS_ROW_FAIL:
@@ -1080,6 +1143,7 @@
                default:
                        _free_sybase_result(result);
                        result = NULL;
+                       retcode = CS_FAIL;              /* Just to be sure */
                        break;
        }
        
@@ -1167,7 +1231,7 @@
                        case CS_DECIMAL_TYPE:
                                result->datafmt[i].maxlength = 
result->datafmt[i].precision + 3;
                                /* numeric(10) vs numeric(10, 1) */
-                               result->numerics[i] = (result->datafmt[i].scale == 0 
&& result->datafmt[i].precision <= 10) ? 1 : 2;
+                               result->numerics[i] = (result->datafmt[i].scale == 0 
&& result->datafmt[i].precision <= 9) ? 1 : 2;
                                break;
                        default:
                                result->datafmt[i].maxlength++;
@@ -1203,6 +1267,9 @@
        }
 
        retcode= php_sybase_fetch_result_row(result, buffered ? 1 : -1);
+       if (retcode == CS_FAIL) {
+               return NULL;
+       }
 
        return result;
 }
@@ -1332,7 +1399,7 @@
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Cannot 
read results");
                        RETURN_FALSE;
                }
-    
+
                switch ((int) restype) {
                        case CS_CMD_FAIL:
                        default:
@@ -1361,7 +1428,6 @@
                                result = php_sybase_fetch_result_set(sybase_ptr, 
buffered, store);
                                if (result == NULL) {
                                        ct_cancel(NULL, sybase_ptr->cmd, 
CS_CANCEL_ALL);
-                                       sybase_ptr->dead = 1;
                                        RETURN_FALSE;
                                }
                                status = Q_RESULT;
@@ -1437,7 +1503,7 @@
                
                /* Retry deadlocks up until deadlock_retry_count times */              
 
                if (sybase_ptr->deadlock && SybCtG(deadlock_retry_count) != -1 && 
++deadlock_count > SybCtG(deadlock_retry_count)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Retried 
deadlock %d times [max: %d], giving up", deadlock_count- 1, 
SybCtG(deadlock_retry_count));
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Retried 
deadlock %d times [max: %ld], giving up\n", deadlock_count- 1, 
SybCtG(deadlock_retry_count));
                        if (result != NULL) {
                                _free_sybase_result(result);
                        }
@@ -1476,7 +1542,7 @@
        }
 
        /* Indicate we have data in case of buffered queries */
-    id= ZEND_REGISTER_RESOURCE(return_value, result, le_result);
+       id= ZEND_REGISTER_RESOURCE(return_value, result, le_result);
        sybase_ptr->active_result_index= buffered ? id : 0;
 }
 
@@ -2038,49 +2104,67 @@
 /* }}} */
 
 
-/* {{{ proto bool sybase_set_message_handler(mixed error_func)
+/* {{{ proto bool sybase_set_message_handler(mixed error_func [, resource connection])
    Set the error handler, to be called when a server message is raised. 
    If error_func is NULL the handler will be deleted */
 PHP_FUNCTION(sybase_set_message_handler)
 {
-       zval ***params;
+       zval **callback, **param, **sybase_link_index= NULL;
        char *name;
-       int argc = ZEND_NUM_ARGS();
+       sybase_link *sybase_ptr;
 
-       if (argc != 1) {
-               WRONG_PARAM_COUNT;
-       }
-       
-       params = safe_emalloc(sizeof(zval **), argc, 0);
+       switch (ZEND_NUM_ARGS()) {
+               case 1:          /* Default message handler */
+                       if (zend_get_parameters_ex(1, &param) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       callback = &SybCtG(callback_name);
+                       break;
 
-       if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
-               efree(params);
-               RETURN_FALSE;
-       }
+               case 2:          /* Connection-based message handler */
+                       if (zend_get_parameters_ex(2, &param, &sybase_link_index) == 
FAILURE) {
+                               RETURN_FALSE;
+                       }                       
+                       ZEND_FETCH_RESOURCE2(sybase_ptr, sybase_link *, 
sybase_link_index, -1, "Sybase-Link", le_link, le_plink);
+                       callback = &sybase_ptr->callback_name;
+                       break;
 
-       if (SybCtG(callback_name)) {
-               zval_dtor(SybCtG(callback_name));
-               SybCtG(callback_name)= NULL;
+               default:
+                       WRONG_PARAM_COUNT;
        }
        
-       if (Z_TYPE_PP(params[0]) == IS_NULL) {
-               efree(params);
-               RETURN_TRUE;
-       }
+       /* Clean out old callback */
+       if (*callback) {
+               zval_ptr_dtor(callback);
+               *callback = NULL;
+       }
+
+       switch (Z_TYPE_PP(param)) {
+               case IS_NULL:
+                       /* Return TRUE to indicate we deleted the message handler */
+                       RETURN_TRUE;
+                       break;
+
+               case IS_ARRAY:
+               case IS_STRING:
+                       /* Either "function", array("class", "function") or 
array($object, "function") */
+                       if (!zend_is_callable(*param, 0, &name)) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "First 
argumented is expected to be a valid callback, '%s' was given", name);
+                               efree(name);
+                               RETURN_FALSE;
+                       }
+                       efree(name);
+                       break;
 
-       if (!zend_is_callable(*params[0], 0, &name)) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argumented is 
expected to be a valid callback, '%s' was given", name);
-               efree(name);
-               efree(params);
-               RETURN_FALSE;
+               default:
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argumented 
is expected to be either NULL, an array or string, %s given", 
zend_zval_type_name(*param));
+                       RETURN_FALSE;
        }
        
-       ALLOC_ZVAL(SybCtG(callback_name));
-       *SybCtG(callback_name) = **params[0];
-       INIT_PZVAL(SybCtG(callback_name));
-       zval_copy_ctor(SybCtG(callback_name));
-       efree(params);
-       efree(name);
+       ALLOC_ZVAL(*callback);
+       **callback = **param;
+       INIT_PZVAL(*callback);
+       zval_copy_ctor(*callback);
        RETURN_TRUE;
 }
 /* }}} */
http://cvs.php.net/diff.php/php-src/ext/sybase_ct/php_sybase_ct.h?r1=1.14.2.2&r2=1.14.2.3&ty=u
Index: php-src/ext/sybase_ct/php_sybase_ct.h
diff -u php-src/ext/sybase_ct/php_sybase_ct.h:1.14.2.2 
php-src/ext/sybase_ct/php_sybase_ct.h:1.14.2.3
--- php-src/ext/sybase_ct/php_sybase_ct.h:1.14.2.2      Fri Aug 29 10:22:13 2003
+++ php-src/ext/sybase_ct/php_sybase_ct.h       Sun Jan 25 15:14:05 2004
@@ -2,7 +2,7 @@
    +----------------------------------------------------------------------+
    | PHP Version 4                                                        |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2003 The PHP Group                                |
+   | Copyright (c) 1997-2004 The PHP Group                                |
    +----------------------------------------------------------------------+
    | This source file is subject to version 3.0 of the PHP license,       |
    | that is bundled with this package in the file LICENSE, and is        |
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_sybase_ct.h,v 1.14.2.2 2003/08/29 14:22:13 sniper Exp $ */
+/* $Id: php_sybase_ct.h,v 1.14.2.3 2004/01/25 20:14:05 thekid Exp $ */
 
 #ifndef PHP_SYBASE_CT_H
 #define PHP_SYBASE_CT_H
@@ -65,6 +65,7 @@
        long default_link;
        long num_links,num_persistent;
        long max_links,max_persistent;
+       long login_timeout;
        long allow_persistent;
        char *appname;
        char *hostname;
@@ -83,6 +84,7 @@
        int dead;
        int active_result_index;
        long affected_rows;
+       zval *callback_name;
 } sybase_link;
 
 #define SYBASE_ROWS_BLOCK 128

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

Reply via email to