]> granicus.if.org Git - php/commitdiff
@- Added ability to define a message handler not only globally, but also
authorTimm Friebe <thekid@php.net>
Sun, 25 Jan 2004 20:03:10 +0000 (20:03 +0000)
committerTimm Friebe <thekid@php.net>
Sun, 25 Jan 2004 20:03:10 +0000 (20:03 +0000)
@  per connection (Timm)
@- Made sybct.login_timeout changeable at runtime (Timm)
@- Added ini option sybct.packet_size which lets you control the packet
@  size (Timm)

ext/sybase_ct/php_sybase_ct.c
ext/sybase_ct/php_sybase_ct.h

index 70cf3f4189aa761f281fffee374415d81a371396..75e5a56bc0ad8affdcd85049a68fe9a6e4c6b220 100644 (file)
@@ -38,53 +38,54 @@ static int le_link, le_plink, le_result;
 #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 @@ static void _close_sybase_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
        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 @@ static CS_RETCODE CS_PUBLIC _client_message_handler(CS_CONTEXT *context, CS_CONN
        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;
-
-       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);
+       int handled = 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);
+               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 @@ static CS_RETCODE CS_PUBLIC _server_message_handler(CS_CONTEXT *context, CS_CONN
 
 
 PHP_INI_BEGIN()
-       STD_PHP_INI_BOOLEAN("sybct.allow_persistent",   "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_persistent,       zend_sybase_globals,    sybase_globals)
-       STD_PHP_INI_ENTRY_EX("sybct.max_persistent",    "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_persistent,         zend_sybase_globals,    sybase_globals, display_link_numbers)
-       STD_PHP_INI_ENTRY_EX("sybct.max_links",         "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_links,                      zend_sybase_globals,    sybase_globals, display_link_numbers)
-       STD_PHP_INI_ENTRY("sybct.min_server_severity",  "10",   PHP_INI_ALL,            OnUpdateLong,           min_server_severity,    zend_sybase_globals,    sybase_globals)
-       STD_PHP_INI_ENTRY("sybct.min_client_severity",  "10",   PHP_INI_ALL,            OnUpdateLong,           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,            OnUpdateLong,           deadlock_retry_count,   zend_sybase_globals,    sybase_globals, display_link_numbers)
+       STD_PHP_INI_BOOLEAN("sybct.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY_EX("sybct.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_sybase_globals, sybase_globals, display_link_numbers)
+       STD_PHP_INI_ENTRY_EX("sybct.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_sybase_globals, sybase_globals, display_link_numbers)
+       STD_PHP_INI_ENTRY("sybct.min_server_severity", "10", PHP_INI_ALL, OnUpdateLong, min_server_severity, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY("sybct.min_client_severity", "10", PHP_INI_ALL, OnUpdateLong, min_client_severity, zend_sybase_globals, sybase_globals)
+       STD_PHP_INI_ENTRY("sybct.login_timeout", "-1", PHP_INI_ALL, OnUpdateLong, 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, OnUpdateLong, 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 @@ static void php_sybase_init_globals(zend_sybase_globals *sybase_globals)
                }
        }
 
-       /* 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 @@ static int php_sybase_do_connect_internal(sybase_link *sybase, char *host, char
                }
        }
 
+       /* 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 @@ static void php_sybase_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                        break;
        }
 
-
        if (!SybCtG(allow_persistent)) {
                persistent=0;
        }
@@ -1073,7 +1120,7 @@ static int php_sybase_fetch_result_row (sybase_result *result, int numrows)
                                                 * 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;
                                }
@@ -2057,49 +2104,67 @@ PHP_FUNCTION(sybase_deadlock_retry_count)
 /* }}} */
 
 
-/* {{{ 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_ptr_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;
        }
 
-       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;
+       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;
+
+               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;
 }
 /* }}} */
index bd19dd1a136e688ad5eca9b108f6876ef1055d3d..5eb7c0285f179043c81863ab787c3f9b94b761cc 100644 (file)
@@ -65,6 +65,7 @@ ZEND_BEGIN_MODULE_GLOBALS(sybase)
        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 @@ typedef struct {
        int dead;
        int active_result_index;
        long affected_rows;
+       zval *callback_name;
 } sybase_link;
 
 #define SYBASE_ROWS_BLOCK 128