From cfac5f5b674a038a35043018145bc61584695fdb Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Tue, 28 Dec 2010 15:16:21 +0000 Subject: [PATCH] extending the API interface - plugins can register themselves with a structure and can be searched. Every plugin can have statistics and they are shown under the statistics of mysqlnd in MINFO. --- ext/mysql/tests/mysql_phpinfo.phpt | 2 +- ext/mysqli/tests/mysqli_phpinfo.phpt | 2 +- ext/mysqlnd/config.w32 | 1 + ext/mysqlnd/config9.m4 | 2 +- ext/mysqlnd/mysqlnd.c | 51 +++-- ext/mysqlnd/mysqlnd.h | 13 +- ext/mysqlnd/mysqlnd_charset.c | 39 +++- ext/mysqlnd/mysqlnd_charset.h | 14 ++ ext/mysqlnd/mysqlnd_debug.c | 33 +++ ext/mysqlnd/mysqlnd_debug.h | 12 + ext/mysqlnd/mysqlnd_plugin.c | 200 +++++++++++++++++ ext/mysqlnd/mysqlnd_priv.h | 8 + ext/mysqlnd/mysqlnd_statistics.c | 322 +++++++++++++-------------- ext/mysqlnd/mysqlnd_statistics.h | 6 - ext/mysqlnd/mysqlnd_structs.h | 42 ++++ ext/mysqlnd/php_mysqlnd.c | 74 ++++-- 16 files changed, 616 insertions(+), 205 deletions(-) create mode 100644 ext/mysqlnd/mysqlnd_plugin.c diff --git a/ext/mysql/tests/mysql_phpinfo.phpt b/ext/mysql/tests/mysql_phpinfo.phpt index 46600ab2d2e..79de939167d 100644 --- a/ext/mysql/tests/mysql_phpinfo.phpt +++ b/ext/mysql/tests/mysql_phpinfo.phpt @@ -51,7 +51,7 @@ if (!stristr($phpinfo, "mysql.allow_persistent")) if ($IS_MYSQLND) { $expected = array( - 'client statistics', + 'mysqlnd statistics', 'bytes_sent', 'bytes_received', 'packets_sent', 'packets_received', 'protocol_overhead_in', 'protocol_overhead_out', 'result_set_queries', 'non_result_set_queries', 'no_index_used', 'bad_index_used', diff --git a/ext/mysqli/tests/mysqli_phpinfo.phpt b/ext/mysqli/tests/mysqli_phpinfo.phpt index d60636ae407..e23a5f696fc 100644 --- a/ext/mysqli/tests/mysqli_phpinfo.phpt +++ b/ext/mysqli/tests/mysqli_phpinfo.phpt @@ -46,7 +46,7 @@ require_once('skipifconnectfailure.inc'); if ($IS_MYSQLND) { $expected = array( - 'client statistics', + 'mysqlnd statistics', 'bytes_sent', 'bytes_received', 'packets_sent', 'packets_received', 'protocol_overhead_in', 'protocol_overhead_out', 'result_set_queries', 'non_result_set_queries', 'no_index_used', 'bad_index_used', diff --git a/ext/mysqlnd/config.w32 b/ext/mysqlnd/config.w32 index 4a32cbcb9d8..6246ce11e44 100644 --- a/ext/mysqlnd/config.w32 +++ b/ext/mysqlnd/config.w32 @@ -12,6 +12,7 @@ if (PHP_MYSQLND != "no") { "mysqlnd_debug.c " + "mysqlnd_loaddata.c " + "mysqlnd_net.c " + + "mysqlnd_plugin.c " + "mysqlnd_ps.c " + "mysqlnd_ps_codec.c " + "mysqlnd_result.c " + diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4 index c6fbc915bb7..470f215a664 100644 --- a/ext/mysqlnd/config9.m4 +++ b/ext/mysqlnd/config9.m4 @@ -18,7 +18,7 @@ if test "$PHP_MYSQLND_ENABLED" = "yes"; then mysqlnd_ps.c mysqlnd_loaddata.c mysqlnd_net.c \ mysqlnd_ps_codec.c mysqlnd_statistics.c \ mysqlnd_result.c mysqlnd_result_meta.c mysqlnd_debug.c\ - mysqlnd_block_alloc.c php_mysqlnd.c" + mysqlnd_block_alloc.c mysqlnd_plugin.c php_mysqlnd.c" PHP_NEW_EXTENSION(mysqlnd, $mysqlnd_sources, no) PHP_ADD_BUILD_DIR([ext/mysqlnd], 1) diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 88a8548eccb..56c67d56d30 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -66,10 +66,14 @@ static zend_bool mysqlnd_library_initted = FALSE; static struct st_mysqlnd_conn_methods *mysqlnd_conn_methods; +static struct st_mysqlnd_plugin_core mysqlnd_plugin_core; + + /* {{{ mysqlnd_library_end */ PHPAPI void mysqlnd_library_end(TSRMLS_D) { if (mysqlnd_library_initted == TRUE) { + mysqlnd_plugin_subsystem_end(TSRMLS_C); mysqlnd_stats_end(mysqlnd_global_stats); mysqlnd_global_stats = NULL; mysqlnd_library_initted = FALSE; @@ -2378,10 +2382,18 @@ PHPAPI void mysqlnd_library_init(TSRMLS_D) _mysqlnd_init_ps_subsystem(); /* Should be calloc, as mnd_calloc will reference LOCK_access*/ mysqlnd_stats_init(&mysqlnd_global_stats, STAT_LAST); + mysqlnd_plugin_subsystem_init(TSRMLS_C); + { + mysqlnd_plugin_core.plugin_header.plugin_stats.values = mysqlnd_global_stats; + mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_core TSRMLS_CC); + } + mysqlnd_example_plugin_register(TSRMLS_C); + mysqlnd_debug_trace_plugin_register(TSRMLS_C); } } /* }}} */ + /* {{{ mysqlnd_conn_get_methods */ PHPAPI struct st_mysqlnd_conn_methods * mysqlnd_conn_get_methods() { @@ -2397,24 +2409,6 @@ PHPAPI void mysqlnd_conn_set_methods(struct st_mysqlnd_conn_methods *methods) /* }}} */ -static unsigned int mysqlnd_plugins_counter = 0; - -/* {{{ mysqlnd_plugin_register */ -PHPAPI unsigned int mysqlnd_plugin_register() -{ - return mysqlnd_plugins_counter++; -} -/* }}} */ - - -/* {{{ mysqlnd_plugin_count */ -PHPAPI unsigned int mysqlnd_plugin_count() -{ - return mysqlnd_plugins_counter; -} -/* }}} */ - - /* {{{ _mysqlnd_plugin_get_plugin_connection_data */ PHPAPI void ** _mysqlnd_plugin_get_plugin_connection_data(const MYSQLND * conn, unsigned int plugin_id TSRMLS_DC) { @@ -2427,6 +2421,27 @@ PHPAPI void ** _mysqlnd_plugin_get_plugin_connection_data(const MYSQLND * conn, } /* }}} */ + +static struct st_mysqlnd_plugin_core mysqlnd_plugin_core = +{ + { + MYSQLND_PLUGIN_API_VERSION, + "mysqlnd", + MYSQLND_VERSION_ID, + MYSQLND_VERSION, + "PHP License 3.01", + "Andrey Hristov , Ulf Wendel , Georg Richter ", + { + NULL, /* will be filled later */ + mysqlnd_stats_values_names, + }, + { + NULL /* plugin shutdown */ + } + } +}; + + /* * Local variables: * tab-width: 4 diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 29ef3939d84..60dab2c5c73 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -22,8 +22,10 @@ #ifndef MYSQLND_H #define MYSQLND_H -#define MYSQLND_VERSION "mysqlnd 5.0.7-dev - 091210 - $Revision$" -#define MYSQLND_VERSION_ID 50007 +#define MYSQLND_VERSION "mysqlnd 5.0.8-dev - 20101228 - $Revision$" +#define MYSQLND_VERSION_ID 50008 + +#define MYSQLND_PLUGIN_API_VERSION 1 /* This forces inlining of some accessor functions */ #define MYSQLND_USE_OPTIMISATIONS 0 @@ -64,7 +66,14 @@ PHPAPI void mysqlnd_library_init(TSRMLS_D); PHPAPI void mysqlnd_library_end(TSRMLS_D); PHPAPI unsigned int mysqlnd_plugin_register(); +PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header * plugin TSRMLS_DC); PHPAPI unsigned int mysqlnd_plugin_count(); +PHPAPI void * _mysqlnd_plugin_find(const char * const name TSRMLS_DC); +#define mysqlnd_plugin_find(name) _mysqlnd_plugin_find((name) TSRMLS_CC); + +PHPAPI void _mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, void * argument TSRMLS_DC); +#define mysqlnd_plugin_apply_with_argument(func, argument) _mysqlnd_plugin_apply_with_argument((func), (argument) TSRMLS_CC); + PHPAPI void ** _mysqlnd_plugin_get_plugin_connection_data(const MYSQLND * conn, unsigned int plugin_id TSRMLS_DC); #define mysqlnd_plugin_get_plugin_connection_data(c, p_id) _mysqlnd_plugin_get_plugin_connection_data((c), (p_id) TSRMLS_CC) diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index 1e058fa1ae5..912af863b9b 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -22,6 +22,7 @@ #include "mysqlnd.h" #include "mysqlnd_priv.h" #include "mysqlnd_debug.h" +#include "mysqlnd_charset.h" /* {{{ utf8 functions */ static unsigned int check_mb_utf8mb3_sequence(const char *start, const char *end) @@ -633,7 +634,7 @@ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_nr(unsigned int charsetnr) /* {{{ mysqlnd_find_charset_name */ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const name) { - const MYSQLND_CHARSET *c = mysqlnd_charsets; + const MYSQLND_CHARSET * c = mysqlnd_charsets; do { if (!strcasecmp(c->name, name)) { @@ -779,6 +780,42 @@ PHPAPI ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, cha } /* }}} */ + +static struct st_mysqlnd_plugin_charsets mysqlnd_plugin_charsets_plugin = +{ + { + MYSQLND_PLUGIN_API_VERSION, + "charsets", + MYSQLND_VERSION_ID, + MYSQLND_VERSION, + "PHP License 3.01", + "Andrey Hristov , Ulf Wendel , Georg Richter ", + { + NULL, /* no statistics , will be filled later if there are some */ + NULL, /* no statistics */ + }, + { + NULL /* plugin shutdown */ + } + }, + {/* methods */ + mysqlnd_find_charset_nr, + mysqlnd_find_charset_name, + mysqlnd_cset_escape_quotes, + mysqlnd_cset_escape_slashes + } +}; + + +/* {{{ mysqlnd_charsets_plugin_register */ +void +mysqlnd_charsets_plugin_register(TSRMLS_D) +{ + mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_charsets_plugin TSRMLS_CC); +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/ext/mysqlnd/mysqlnd_charset.h b/ext/mysqlnd/mysqlnd_charset.h index c5f0d7cb119..4c6401fa8e5 100644 --- a/ext/mysqlnd/mysqlnd_charset.h +++ b/ext/mysqlnd/mysqlnd_charset.h @@ -27,6 +27,20 @@ PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const charset, c PHPAPI ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC); +struct st_mysqlnd_plugin_charsets +{ + const struct st_mysqlnd_plugin_header plugin_header; + struct + { + const MYSQLND_CHARSET * (*const find_charset_by_nr)(unsigned int charsetnr); + const MYSQLND_CHARSET * (*const find_charset_by_name)(const char * const name); + unsigned long (*const escape_quotes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, size_t escapestr_len TSRMLS_DC); + unsigned long (*const escape_slashes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, size_t escapestr_len TSRMLS_DC); + } methods; +}; + +void mysqlnd_charsets_plugin_register(TSRMLS_D); + #endif /* MYSQLND_CHARSET_H */ /* diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index d54ae01098c..acd8be308e8 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -1856,6 +1856,39 @@ PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC) return res; } + +static struct st_mysqlnd_plugin_trace_log mysqlnd_plugin_trace_log_plugin = +{ + { + MYSQLND_PLUGIN_API_VERSION, + "debug_trace", + MYSQLND_VERSION_ID, + MYSQLND_VERSION, + "PHP License 3.01", + "Andrey Hristov , Ulf Wendel , Georg Richter ", + { + NULL, /* no statistics , will be filled later if there are some */ + NULL, /* no statistics */ + }, + { + NULL /* plugin shutdown */ + } + }, + {/* methods */ + mysqlnd_debug_init, + mysqlnd_get_backtrace + } +}; + +/* {{{ mysqlnd_debug_trace_plugin_register */ +void +mysqlnd_debug_trace_plugin_register(TSRMLS_D) +{ + mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_trace_log_plugin TSRMLS_CC); +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h index 060b97c04d4..9c37dce4e93 100644 --- a/ext/mysqlnd/mysqlnd_debug.h +++ b/ext/mysqlnd/mysqlnd_debug.h @@ -59,6 +59,18 @@ struct st_mysqlnd_debug const char ** skip_functions; }; +struct st_mysqlnd_plugin_trace_log +{ + struct st_mysqlnd_plugin_header plugin_header; + struct + { + MYSQLND_DEBUG * (*trace_instance_init)(const char * skip_functions[] TSRMLS_DC); + char * (*get_backtrace)(uint max_levels, size_t * length TSRMLS_DC); + } methods; +}; + +void mysqlnd_debug_trace_plugin_register(TSRMLS_D); + PHPAPI extern const char * mysqlnd_debug_std_no_trace_funcs[]; PHPAPI MYSQLND_DEBUG * mysqlnd_debug_init(const char * skip_functions[] TSRMLS_DC); diff --git a/ext/mysqlnd/mysqlnd_plugin.c b/ext/mysqlnd/mysqlnd_plugin.c new file mode 100644 index 00000000000..c2324a8f58b --- /dev/null +++ b/ext/mysqlnd/mysqlnd_plugin.c @@ -0,0 +1,200 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter | + | Andrey Hristov | + | Ulf Wendel | + +----------------------------------------------------------------------+ +*/ + +/* $Id: mysqlnd.c 306407 2010-12-16 12:56:19Z andrey $ */ +#include "php.h" +#include "mysqlnd.h" +#include "mysqlnd_wireprotocol.h" +#include "mysqlnd_priv.h" +#include "mysqlnd_result.h" +#include "mysqlnd_statistics.h" +#include "mysqlnd_charset.h" +#include "mysqlnd_debug.h" +/* for php_get_current_user() */ +#include "ext/standard/basic_functions.h" + + +/*--------------------------------------------------------------------*/ + +static enum_func_status mysqlnd_example_plugin_end(void * p TSRMLS_DC); + +static MYSQLND_STATS * mysqlnd_plugin_example_stats = NULL; + +enum mysqlnd_plugin_example_collected_stats +{ + EXAMPLE_STAT1, + EXAMPLE_STAT2, + EXAMPLE_STAT_LAST +}; + +static const MYSQLND_STRING mysqlnd_plugin_example_stats_values_names[EXAMPLE_STAT_LAST] = +{ + { MYSQLND_STR_W_LEN("stat1") }, + { MYSQLND_STR_W_LEN("stat2") } +}; + +static struct st_mysqlnd_typeii_plugin_example mysqlnd_example_plugin = +{ + { + MYSQLND_PLUGIN_API_VERSION, + "example", + 10001L, + "1.00.01", + "PHP License", + "Andrey Hristov ", + { + NULL, /* will be filled later */ + mysqlnd_plugin_example_stats_values_names, + }, + { + mysqlnd_example_plugin_end + } + }, + NULL, /* methods */ +}; + + +/* {{{ mysqlnd_plugin_subsystem_init */ +static +enum_func_status mysqlnd_example_plugin_end(void * p TSRMLS_DC) +{ +#if A0 + struct st_mysqlnd_typeii_plugin_example * plugin = (struct st_mysqlnd_typeii_plugin_example *) p; +#endif + DBG_ENTER("mysqlnd_example_plugin_end"); + + DBG_RETURN(PASS); +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_subsystem_init */ +void +mysqlnd_example_plugin_register(TSRMLS_D) +{ + mysqlnd_stats_init(&mysqlnd_plugin_example_stats, EXAMPLE_STAT_LAST); + mysqlnd_example_plugin.plugin_header.plugin_stats.values = mysqlnd_plugin_example_stats; + mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_example_plugin TSRMLS_CC); +} +/* }}} */ + +/*--------------------------------------------------------------------*/ + +static HashTable mysqlnd_registered_plugins; + +static unsigned int mysqlnd_plugins_counter = 0; + + +/* {{{ mysqlnd_plugin_subsystem_init */ +void +mysqlnd_plugin_subsystem_init(TSRMLS_D) +{ + zend_hash_init(&mysqlnd_registered_plugins, 4 /* initial hash size */, NULL /* hash_func */, NULL /* dtor */, TRUE /* pers */); +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_subsystem_init */ +int +mysqlnd_plugin_end_apply_func(void *pDest TSRMLS_DC) +{ + struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **) pDest; + if (plugin_header->m.plugin_shutdown) { + plugin_header->m.plugin_shutdown(plugin_header TSRMLS_CC); + } + return ZEND_HASH_APPLY_REMOVE; +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_subsystem_end */ +void +mysqlnd_plugin_subsystem_end(TSRMLS_D) +{ + zend_hash_apply(&mysqlnd_registered_plugins, mysqlnd_plugin_end_apply_func TSRMLS_CC); + zend_hash_destroy(&mysqlnd_registered_plugins); +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_register */ +PHPAPI unsigned int mysqlnd_plugin_register() +{ + TSRMLS_FETCH(); + return mysqlnd_plugin_register_ex(NULL TSRMLS_CC); +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_register */ +PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header * plugin TSRMLS_DC) +{ + if (plugin) { + if (plugin->plugin_api_version == MYSQLND_PLUGIN_API_VERSION) { + zend_hash_update(&mysqlnd_registered_plugins, plugin->plugin_name, strlen(plugin->plugin_name) + 1, &plugin, sizeof(void *), NULL); + ++mysqlnd_plugins_counter; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Plugin API version mismatch while loading plugin %s. Expected %d, got %d", + plugin->plugin_name, MYSQLND_PLUGIN_API_VERSION, plugin->plugin_api_version); + } + } + return mysqlnd_plugins_counter; + +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_find */ +PHPAPI void * _mysqlnd_plugin_find(const char * const name TSRMLS_DC) +{ + void * plugin; + if (SUCCESS == zend_hash_find(&mysqlnd_registered_plugins, name, strlen(name) + 1, (void **) &plugin)) { + return (void *)*(char **) plugin; + } + return NULL; + +} +/* }}} */ + + +/* {{{ _mysqlnd_plugin_apply_with_argument */ +PHPAPI void _mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, void * argument TSRMLS_DC) +{ + zend_hash_apply_with_argument(&mysqlnd_registered_plugins, apply_func, argument TSRMLS_CC); +} +/* }}} */ + + +/* {{{ mysqlnd_plugin_count */ +PHPAPI unsigned int mysqlnd_plugin_count() +{ + return mysqlnd_plugins_counter; +} +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index 4681c8cbda7..8fd095cb84e 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -67,6 +67,7 @@ } #endif +#define MYSQLND_STR_W_LEN(str) str, (sizeof(str) - 1) #define MYSQLND_DEBUG_DUMP_TIME 1 #define MYSQLND_DEBUG_DUMP_TRACE 2 @@ -188,6 +189,13 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode, unsigned int byte_count TSRMLS_DC); +void mysqlnd_plugin_subsystem_init(TSRMLS_D); +void mysqlnd_plugin_subsystem_end(TSRMLS_D); + + + +void mysqlnd_example_plugin_register(TSRMLS_D); + #endif /* MYSQLND_PRIV_H */ diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index a025994f818..fdcd27518e2 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -26,173 +26,171 @@ #include "mysqlnd_debug.h" -#define STR_W_LEN(str) str, (sizeof(str) - 1) - /* {{{ mysqlnd_stats_values_names */ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] = { - { STR_W_LEN("bytes_sent") }, - { STR_W_LEN("bytes_received") }, - { STR_W_LEN("packets_sent") }, - { STR_W_LEN("packets_received") }, - { STR_W_LEN("protocol_overhead_in") }, - { STR_W_LEN("protocol_overhead_out") }, - { STR_W_LEN("bytes_received_ok_packet") }, - { STR_W_LEN("bytes_received_eof_packet") }, - { STR_W_LEN("bytes_received_rset_header_packet") }, - { STR_W_LEN("bytes_received_rset_field_meta_packet") }, - { STR_W_LEN("bytes_received_rset_row_packet") }, - { STR_W_LEN("bytes_received_prepare_response_packet") }, - { STR_W_LEN("bytes_received_change_user_packet") }, - { STR_W_LEN("packets_sent_command") }, - { STR_W_LEN("packets_received_ok") }, - { STR_W_LEN("packets_received_eof") }, - { STR_W_LEN("packets_received_rset_header") }, - { STR_W_LEN("packets_received_rset_field_meta") }, - { STR_W_LEN("packets_received_rset_row") }, - { STR_W_LEN("packets_received_prepare_response") }, - { STR_W_LEN("packets_received_change_user") }, - { STR_W_LEN("result_set_queries") }, - { STR_W_LEN("non_result_set_queries") }, - { STR_W_LEN("no_index_used") }, - { STR_W_LEN("bad_index_used") }, - { STR_W_LEN("slow_queries") }, - { STR_W_LEN("buffered_sets") }, - { STR_W_LEN("unbuffered_sets") }, - { STR_W_LEN("ps_buffered_sets") }, - { STR_W_LEN("ps_unbuffered_sets") }, - { STR_W_LEN("flushed_normal_sets") }, - { STR_W_LEN("flushed_ps_sets") }, - { STR_W_LEN("ps_prepared_never_executed") }, - { STR_W_LEN("ps_prepared_once_executed") }, - { STR_W_LEN("rows_fetched_from_server_normal") }, - { STR_W_LEN("rows_fetched_from_server_ps") }, - { STR_W_LEN("rows_buffered_from_client_normal") }, - { STR_W_LEN("rows_buffered_from_client_ps") }, - { STR_W_LEN("rows_fetched_from_client_normal_buffered") }, - { STR_W_LEN("rows_fetched_from_client_normal_unbuffered") }, - { STR_W_LEN("rows_fetched_from_client_ps_buffered") }, - { STR_W_LEN("rows_fetched_from_client_ps_unbuffered") }, - { STR_W_LEN("rows_fetched_from_client_ps_cursor") }, - { STR_W_LEN("rows_affected_normal") }, - { STR_W_LEN("rows_affected_ps") }, - { STR_W_LEN("rows_skipped_normal") }, - { STR_W_LEN("rows_skipped_ps") }, - { STR_W_LEN("copy_on_write_saved") }, - { STR_W_LEN("copy_on_write_performed") }, - { STR_W_LEN("command_buffer_too_small") }, - { STR_W_LEN("connect_success") }, - { STR_W_LEN("connect_failure") }, - { STR_W_LEN("connection_reused") }, - { STR_W_LEN("reconnect") }, - { STR_W_LEN("pconnect_success") }, - { STR_W_LEN("active_connections") }, - { STR_W_LEN("active_persistent_connections") }, - { STR_W_LEN("explicit_close") }, - { STR_W_LEN("implicit_close") }, - { STR_W_LEN("disconnect_close") }, - { STR_W_LEN("in_middle_of_command_close") }, - { STR_W_LEN("explicit_free_result") }, - { STR_W_LEN("implicit_free_result") }, - { STR_W_LEN("explicit_stmt_close") }, - { STR_W_LEN("implicit_stmt_close") }, - { STR_W_LEN("mem_emalloc_count") }, - { STR_W_LEN("mem_emalloc_amount") }, - { STR_W_LEN("mem_ecalloc_count") }, - { STR_W_LEN("mem_ecalloc_amount") }, - { STR_W_LEN("mem_erealloc_count") }, - { STR_W_LEN("mem_erealloc_amount") }, - { STR_W_LEN("mem_efree_count") }, - { STR_W_LEN("mem_efree_amount") }, - { STR_W_LEN("mem_malloc_count") }, - { STR_W_LEN("mem_malloc_amount") }, - { STR_W_LEN("mem_calloc_count") }, - { STR_W_LEN("mem_calloc_amount") }, - { STR_W_LEN("mem_realloc_count") }, - { STR_W_LEN("mem_realloc_amount") }, - { STR_W_LEN("mem_free_count") }, - { STR_W_LEN("mem_free_amount") }, - { STR_W_LEN("mem_estrndup_count") }, - { STR_W_LEN("mem_strndup_count") }, - { STR_W_LEN("mem_estndup_count") }, - { STR_W_LEN("mem_strdup_count") }, - { STR_W_LEN("proto_text_fetched_null") }, - { STR_W_LEN("proto_text_fetched_bit") }, - { STR_W_LEN("proto_text_fetched_tinyint") }, - { STR_W_LEN("proto_text_fetched_short") }, - { STR_W_LEN("proto_text_fetched_int24") }, - { STR_W_LEN("proto_text_fetched_int") }, - { STR_W_LEN("proto_text_fetched_bigint") }, - { STR_W_LEN("proto_text_fetched_decimal") }, - { STR_W_LEN("proto_text_fetched_float") }, - { STR_W_LEN("proto_text_fetched_double") }, - { STR_W_LEN("proto_text_fetched_date") }, - { STR_W_LEN("proto_text_fetched_year") }, - { STR_W_LEN("proto_text_fetched_time") }, - { STR_W_LEN("proto_text_fetched_datetime") }, - { STR_W_LEN("proto_text_fetched_timestamp") }, - { STR_W_LEN("proto_text_fetched_string") }, - { STR_W_LEN("proto_text_fetched_blob") }, - { STR_W_LEN("proto_text_fetched_enum") }, - { STR_W_LEN("proto_text_fetched_set") }, - { STR_W_LEN("proto_text_fetched_geometry") }, - { STR_W_LEN("proto_text_fetched_other") }, - { STR_W_LEN("proto_binary_fetched_null") }, - { STR_W_LEN("proto_binary_fetched_bit") }, - { STR_W_LEN("proto_binary_fetched_tinyint") }, - { STR_W_LEN("proto_binary_fetched_short") }, - { STR_W_LEN("proto_binary_fetched_int24") }, - { STR_W_LEN("proto_binary_fetched_int") }, - { STR_W_LEN("proto_binary_fetched_bigint") }, - { STR_W_LEN("proto_binary_fetched_decimal") }, - { STR_W_LEN("proto_binary_fetched_float") }, - { STR_W_LEN("proto_binary_fetched_double") }, - { STR_W_LEN("proto_binary_fetched_date") }, - { STR_W_LEN("proto_binary_fetched_year") }, - { STR_W_LEN("proto_binary_fetched_time") }, - { STR_W_LEN("proto_binary_fetched_datetime") }, - { STR_W_LEN("proto_binary_fetched_timestamp") }, - { STR_W_LEN("proto_binary_fetched_string") }, - { STR_W_LEN("proto_binary_fetched_blob") }, - { STR_W_LEN("proto_binary_fetched_enum") }, - { STR_W_LEN("proto_binary_fetched_set") }, - { STR_W_LEN("proto_binary_fetched_geometry") }, - { STR_W_LEN("proto_binary_fetched_other") }, - { STR_W_LEN("init_command_executed_count") }, - { STR_W_LEN("init_command_failed_count") }, - { STR_W_LEN("com_quit") }, - { STR_W_LEN("com_init_db") }, - { STR_W_LEN("com_query") }, - { STR_W_LEN("com_field_list") }, - { STR_W_LEN("com_create_db") }, - { STR_W_LEN("com_drop_db") }, - { STR_W_LEN("com_refresh") }, - { STR_W_LEN("com_shutdown") }, - { STR_W_LEN("com_statistics") }, - { STR_W_LEN("com_process_info") }, - { STR_W_LEN("com_connect") }, - { STR_W_LEN("com_process_kill") }, - { STR_W_LEN("com_debug") }, - { STR_W_LEN("com_ping") }, - { STR_W_LEN("com_time") }, - { STR_W_LEN("com_delayed_insert") }, - { STR_W_LEN("com_change_user") }, - { STR_W_LEN("com_binlog_dump") }, - { STR_W_LEN("com_table_dump") }, - { STR_W_LEN("com_connect_out") }, - { STR_W_LEN("com_register_slave") }, - { STR_W_LEN("com_stmt_prepare") }, - { STR_W_LEN("com_stmt_execute") }, - { STR_W_LEN("com_stmt_send_long_data") }, - { STR_W_LEN("com_stmt_close") }, - { STR_W_LEN("com_stmt_reset") }, - { STR_W_LEN("com_stmt_set_option") }, - { STR_W_LEN("com_stmt_fetch") }, - { STR_W_LEN("com_deamon") }, - { STR_W_LEN("bytes_received_real_data_normal") }, - { STR_W_LEN("bytes_received_real_data_ps") } + { MYSQLND_STR_W_LEN("bytes_sent") }, + { MYSQLND_STR_W_LEN("bytes_received") }, + { MYSQLND_STR_W_LEN("packets_sent") }, + { MYSQLND_STR_W_LEN("packets_received") }, + { MYSQLND_STR_W_LEN("protocol_overhead_in") }, + { MYSQLND_STR_W_LEN("protocol_overhead_out") }, + { MYSQLND_STR_W_LEN("bytes_received_ok_packet") }, + { MYSQLND_STR_W_LEN("bytes_received_eof_packet") }, + { MYSQLND_STR_W_LEN("bytes_received_rset_header_packet") }, + { MYSQLND_STR_W_LEN("bytes_received_rset_field_meta_packet") }, + { MYSQLND_STR_W_LEN("bytes_received_rset_row_packet") }, + { MYSQLND_STR_W_LEN("bytes_received_prepare_response_packet") }, + { MYSQLND_STR_W_LEN("bytes_received_change_user_packet") }, + { MYSQLND_STR_W_LEN("packets_sent_command") }, + { MYSQLND_STR_W_LEN("packets_received_ok") }, + { MYSQLND_STR_W_LEN("packets_received_eof") }, + { MYSQLND_STR_W_LEN("packets_received_rset_header") }, + { MYSQLND_STR_W_LEN("packets_received_rset_field_meta") }, + { MYSQLND_STR_W_LEN("packets_received_rset_row") }, + { MYSQLND_STR_W_LEN("packets_received_prepare_response") }, + { MYSQLND_STR_W_LEN("packets_received_change_user") }, + { MYSQLND_STR_W_LEN("result_set_queries") }, + { MYSQLND_STR_W_LEN("non_result_set_queries") }, + { MYSQLND_STR_W_LEN("no_index_used") }, + { MYSQLND_STR_W_LEN("bad_index_used") }, + { MYSQLND_STR_W_LEN("slow_queries") }, + { MYSQLND_STR_W_LEN("buffered_sets") }, + { MYSQLND_STR_W_LEN("unbuffered_sets") }, + { MYSQLND_STR_W_LEN("ps_buffered_sets") }, + { MYSQLND_STR_W_LEN("ps_unbuffered_sets") }, + { MYSQLND_STR_W_LEN("flushed_normal_sets") }, + { MYSQLND_STR_W_LEN("flushed_ps_sets") }, + { MYSQLND_STR_W_LEN("ps_prepared_never_executed") }, + { MYSQLND_STR_W_LEN("ps_prepared_once_executed") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_server_normal") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_server_ps") }, + { MYSQLND_STR_W_LEN("rows_buffered_from_client_normal") }, + { MYSQLND_STR_W_LEN("rows_buffered_from_client_ps") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_client_normal_buffered") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_client_normal_unbuffered") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_client_ps_buffered") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_client_ps_unbuffered") }, + { MYSQLND_STR_W_LEN("rows_fetched_from_client_ps_cursor") }, + { MYSQLND_STR_W_LEN("rows_affected_normal") }, + { MYSQLND_STR_W_LEN("rows_affected_ps") }, + { MYSQLND_STR_W_LEN("rows_skipped_normal") }, + { MYSQLND_STR_W_LEN("rows_skipped_ps") }, + { MYSQLND_STR_W_LEN("copy_on_write_saved") }, + { MYSQLND_STR_W_LEN("copy_on_write_performed") }, + { MYSQLND_STR_W_LEN("command_buffer_too_small") }, + { MYSQLND_STR_W_LEN("connect_success") }, + { MYSQLND_STR_W_LEN("connect_failure") }, + { MYSQLND_STR_W_LEN("connection_reused") }, + { MYSQLND_STR_W_LEN("reconnect") }, + { MYSQLND_STR_W_LEN("pconnect_success") }, + { MYSQLND_STR_W_LEN("active_connections") }, + { MYSQLND_STR_W_LEN("active_persistent_connections") }, + { MYSQLND_STR_W_LEN("explicit_close") }, + { MYSQLND_STR_W_LEN("implicit_close") }, + { MYSQLND_STR_W_LEN("disconnect_close") }, + { MYSQLND_STR_W_LEN("in_middle_of_command_close") }, + { MYSQLND_STR_W_LEN("explicit_free_result") }, + { MYSQLND_STR_W_LEN("implicit_free_result") }, + { MYSQLND_STR_W_LEN("explicit_stmt_close") }, + { MYSQLND_STR_W_LEN("implicit_stmt_close") }, + { MYSQLND_STR_W_LEN("mem_emalloc_count") }, + { MYSQLND_STR_W_LEN("mem_emalloc_amount") }, + { MYSQLND_STR_W_LEN("mem_ecalloc_count") }, + { MYSQLND_STR_W_LEN("mem_ecalloc_amount") }, + { MYSQLND_STR_W_LEN("mem_erealloc_count") }, + { MYSQLND_STR_W_LEN("mem_erealloc_amount") }, + { MYSQLND_STR_W_LEN("mem_efree_count") }, + { MYSQLND_STR_W_LEN("mem_efree_amount") }, + { MYSQLND_STR_W_LEN("mem_malloc_count") }, + { MYSQLND_STR_W_LEN("mem_malloc_amount") }, + { MYSQLND_STR_W_LEN("mem_calloc_count") }, + { MYSQLND_STR_W_LEN("mem_calloc_amount") }, + { MYSQLND_STR_W_LEN("mem_realloc_count") }, + { MYSQLND_STR_W_LEN("mem_realloc_amount") }, + { MYSQLND_STR_W_LEN("mem_free_count") }, + { MYSQLND_STR_W_LEN("mem_free_amount") }, + { MYSQLND_STR_W_LEN("mem_estrndup_count") }, + { MYSQLND_STR_W_LEN("mem_strndup_count") }, + { MYSQLND_STR_W_LEN("mem_estndup_count") }, + { MYSQLND_STR_W_LEN("mem_strdup_count") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_null") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_bit") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_tinyint") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_short") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_int24") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_int") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_bigint") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_decimal") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_float") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_double") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_date") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_year") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_time") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_datetime") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_timestamp") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_string") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_blob") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_enum") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_set") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_geometry") }, + { MYSQLND_STR_W_LEN("proto_text_fetched_other") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_null") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_bit") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_tinyint") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_short") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_int24") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_int") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_bigint") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_decimal") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_float") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_double") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_date") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_year") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_time") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_datetime") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_timestamp") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_string") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_blob") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_enum") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_set") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_geometry") }, + { MYSQLND_STR_W_LEN("proto_binary_fetched_other") }, + { MYSQLND_STR_W_LEN("init_command_executed_count") }, + { MYSQLND_STR_W_LEN("init_command_failed_count") }, + { MYSQLND_STR_W_LEN("com_quit") }, + { MYSQLND_STR_W_LEN("com_init_db") }, + { MYSQLND_STR_W_LEN("com_query") }, + { MYSQLND_STR_W_LEN("com_field_list") }, + { MYSQLND_STR_W_LEN("com_create_db") }, + { MYSQLND_STR_W_LEN("com_drop_db") }, + { MYSQLND_STR_W_LEN("com_refresh") }, + { MYSQLND_STR_W_LEN("com_shutdown") }, + { MYSQLND_STR_W_LEN("com_statistics") }, + { MYSQLND_STR_W_LEN("com_process_info") }, + { MYSQLND_STR_W_LEN("com_connect") }, + { MYSQLND_STR_W_LEN("com_process_kill") }, + { MYSQLND_STR_W_LEN("com_debug") }, + { MYSQLND_STR_W_LEN("com_ping") }, + { MYSQLND_STR_W_LEN("com_time") }, + { MYSQLND_STR_W_LEN("com_delayed_insert") }, + { MYSQLND_STR_W_LEN("com_change_user") }, + { MYSQLND_STR_W_LEN("com_binlog_dump") }, + { MYSQLND_STR_W_LEN("com_table_dump") }, + { MYSQLND_STR_W_LEN("com_connect_out") }, + { MYSQLND_STR_W_LEN("com_register_slave") }, + { MYSQLND_STR_W_LEN("com_stmt_prepare") }, + { MYSQLND_STR_W_LEN("com_stmt_execute") }, + { MYSQLND_STR_W_LEN("com_stmt_send_long_data") }, + { MYSQLND_STR_W_LEN("com_stmt_close") }, + { MYSQLND_STR_W_LEN("com_stmt_reset") }, + { MYSQLND_STR_W_LEN("com_stmt_set_option") }, + { MYSQLND_STR_W_LEN("com_stmt_fetch") }, + { MYSQLND_STR_W_LEN("com_deamon") }, + { MYSQLND_STR_W_LEN("bytes_received_real_data_normal") }, + { MYSQLND_STR_W_LEN("bytes_received_real_data_ps") } }; /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_statistics.h b/ext/mysqlnd/mysqlnd_statistics.h index b0c2f8bbe8a..d66ebea02ec 100644 --- a/ext/mysqlnd/mysqlnd_statistics.h +++ b/ext/mysqlnd/mysqlnd_statistics.h @@ -26,12 +26,6 @@ PHPAPI extern MYSQLND_STATS * mysqlnd_global_stats; -typedef struct st_mysqlnd_string -{ - char *s; - size_t l; -} MYSQLND_STRING; - extern const MYSQLND_STRING mysqlnd_stats_values_names[]; #ifdef ZTS diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index a04fc49e3cd..ff3470b2813 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -921,4 +921,46 @@ struct st_mysqlnd_stmt zend_bool persistent; }; + +typedef struct st_mysqlnd_string +{ + char *s; + size_t l; +} MYSQLND_STRING; + + +struct st_mysqlnd_plugin_header +{ + unsigned int plugin_api_version; + const char * plugin_name; + unsigned long plugin_version; + const char * plugin_string_version; + const char * plugin_license; + const char * plugin_author; + struct + { + MYSQLND_STATS * values; + const MYSQLND_STRING * names; + } plugin_stats; + + struct + { + enum_func_status (*plugin_shutdown)(void * plugin TSRMLS_DC); + } m; +}; + + +struct st_mysqlnd_plugin_core +{ + struct st_mysqlnd_plugin_header plugin_header; +}; + + +struct st_mysqlnd_typeii_plugin_example +{ + struct st_mysqlnd_plugin_header plugin_header; + void * methods; + unsigned int counter; +}; + #endif /* MYSQLND_STRUCTS_H */ diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c index da9a90dfafd..1a944f0f2ed 100644 --- a/ext/mysqlnd/php_mysqlnd.c +++ b/ext/mysqlnd/php_mysqlnd.c @@ -24,7 +24,9 @@ #include "mysqlnd.h" #include "mysqlnd_priv.h" #include "mysqlnd_debug.h" +#include "mysqlnd_statistics.h" #include "ext/standard/info.h" +#include "ext/standard/php_smart_str.h" /* {{{ mysqlnd_functions[] * @@ -92,12 +94,51 @@ PHPAPI void mysqlnd_minfo_print_hash(zval *values) /* }}} */ +/* {{{ mysqlnd_minfo_dump_plugin_stats */ +static int +mysqlnd_minfo_dump_plugin_stats(void *pDest, void * argument TSRMLS_DC) +{ + struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **) pDest; + if (plugin_header->plugin_stats.values) { + char buf[64]; + zval values; + snprintf(buf, sizeof(buf), "%s statistics", plugin_header->plugin_name); + + mysqlnd_fill_stats_hash(plugin_header->plugin_stats.values, plugin_header->plugin_stats.names, &values TSRMLS_CC ZEND_FILE_LINE_CC); + + php_info_print_table_start(); + php_info_print_table_header(2, buf, ""); + mysqlnd_minfo_print_hash(&values); + php_info_print_table_end(); + zval_dtor(&values); + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + + +/* {{{ mysqlnd_minfo_dump_loaded_plugins */ +static int +mysqlnd_minfo_dump_loaded_plugins(void *pDest, void * buf TSRMLS_DC) +{ + smart_str * buffer = (smart_str *) buf; + struct st_mysqlnd_plugin_header * plugin_header = *(struct st_mysqlnd_plugin_header **) pDest; + if (plugin_header->plugin_name) { + if (buffer->len) { + smart_str_appendc(buffer, ','); + } + smart_str_appends(buffer, plugin_header->plugin_name); + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + + /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(mysqlnd) { char buf[32]; - zval values; php_info_print_table_start(); php_info_print_table_header(2, "mysqlnd", "enabled"); @@ -126,14 +167,17 @@ PHP_MINFO_FUNCTION(mysqlnd) php_info_print_table_row(2, "Tracing", MYSQLND_G(debug)? MYSQLND_G(debug):"n/a"); php_info_print_table_end(); - /* Print client stats */ - php_info_print_table_start(); - php_info_print_table_header(2, "Client statistics", ""); - mysqlnd_get_client_stats(&values); - mysqlnd_minfo_print_hash(&values); + /* loaded plugins */ + { + smart_str tmp_str = {0, 0, 0}; + mysqlnd_plugin_apply_with_argument(mysqlnd_minfo_dump_loaded_plugins, &tmp_str); + smart_str_0(&tmp_str); + php_info_print_table_row(2, "Loaded plugins", tmp_str.c); + smart_str_free(&tmp_str); + } - zval_dtor(&values); - php_info_print_table_end(); + /* Print client stats */ + mysqlnd_plugin_apply_with_argument(mysqlnd_minfo_dump_plugin_stats, NULL); } /* }}} */ @@ -230,12 +274,16 @@ static PHP_MSHUTDOWN_FUNCTION(mysqlnd) static PHP_RINIT_FUNCTION(mysqlnd) { if (MYSQLND_G(debug)) { - MYSQLND_DEBUG *dbg = mysqlnd_debug_init(mysqlnd_debug_std_no_trace_funcs TSRMLS_CC); - if (!dbg) { - return FAILURE; + MYSQLND_G(dbg) = NULL; + struct st_mysqlnd_plugin_trace_log * trace_log_plugin = mysqlnd_plugin_find("debug_trace"); + if (trace_log_plugin) { + MYSQLND_DEBUG * dbg = trace_log_plugin->methods.trace_instance_init(mysqlnd_debug_std_no_trace_funcs TSRMLS_CC); + if (!dbg) { + return FAILURE; + } + dbg->m->set_mode(dbg, MYSQLND_G(debug)); + MYSQLND_G(dbg) = dbg; } - dbg->m->set_mode(dbg, MYSQLND_G(debug)); - MYSQLND_G(dbg) = dbg; } return SUCCESS; }