#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}
};
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);
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;
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) {
}
}
- /* 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;
}
}
}
+ /* 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) {
break;
}
-
if (!SybCtG(allow_persistent)) {
persistent=0;
}
* 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;
}
/* }}} */
-/* {{{ 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, ¶m) == 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, ¶m, &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;
}
/* }}} */