]> granicus.if.org Git - php/commitdiff
added profiler support
authorGeorg Richter <georg@php.net>
Mon, 3 Mar 2003 22:36:47 +0000 (22:36 +0000)
committerGeorg Richter <georg@php.net>
Mon, 3 Mar 2003 22:36:47 +0000 (22:36 +0000)
ext/mysqli/config.m4
ext/mysqli/mysqli.c
ext/mysqli/mysqli_fe.c
ext/mysqli/mysqli_nonapi.c
ext/mysqli/mysqli_profiler.c [new file with mode: 0644]
ext/mysqli/php_mysqli.h

index e7c34850b7a6e136b2332642001f9549b90f483f..4934cb7819886a99471712fef7903d5d02c354fe 100644 (file)
@@ -54,5 +54,5 @@ if test "$PHP_MYSQLI" != "no"; then
   ])
   PHP_SUBST(MYSQLI_SHARED_LIBADD)
 
-  PHP_NEW_EXTENSION(mysqli, mysqli.c mysqli_api.c mysqli_nonapi.c mysqli_fe.c, $ext_shared)
+  PHP_NEW_EXTENSION(mysqli, mysqli.c mysqli_api.c mysqli_nonapi.c mysqli_fe.c mysqli_profiler.c, $ext_shared)
 fi
index 361132784d9fa3aa5cbfb3f6820fbd60c8600caf..4d6a98f62664637b44412441e07e9298294cd77e 100644 (file)
@@ -176,6 +176,7 @@ static void php_mysqli_init_globals(zend_mysqli_globals *mysqli_globals)
        mysqli_globals->default_user = NULL;
        mysqli_globals->default_pw = NULL;
        mysqli_globals->default_socket = NULL;
+       memset(&mysqli_globals->profiler, '\0', sizeof(PROFILER));
 }
 /* }}} */
 
index b7e00e0b80229a3a75a7b760f5740688ffb11d99..7c1e1569fb4d830c92e39bccc2c4f61e813def59 100644 (file)
@@ -102,6 +102,7 @@ function_entry mysqli_functions[] = {
        PHP_FE(mysqli_send_long_data,                                           NULL)
        PHP_FE(mysqli_send_query,                                                       NULL)
        PHP_FALIAS(mysqli_set_opt,              mysqli_options,         NULL)
+       PHP_FE(mysqli_set_profiler_opt,                                         NULL)
        PHP_FE(mysqli_slave_query,                                                      NULL)
        PHP_FE(mysqli_ssl_set,                                                          NULL)
        PHP_FE(mysqli_stat,                                                                     NULL)
index a9889261738a70563078bb51bceddc631088773c..0c824f02bd1e51bebd7e7dd005852fed1b4e8023 100644 (file)
@@ -1,8 +1,8 @@
 /*
   +----------------------------------------------------------------------+
-  | PHP Version 4                                                        |
+  | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
-  | Copyright (c) 1997-2002 The PHP Group                                |
+  | Copyright (c) 1997-2003 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
@@ -121,8 +121,20 @@ PHP_FUNCTION(mysqli_query) {
        }
        MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, &mysql_link, "mysqli_link"); 
 
-       if (mysql_real_query(mysql, query, query_len)) {
-               RETURN_FALSE;
+       /* profiler reports */
+       if (MyG(profiler.active)) {
+               MYSQLI_PROFILER_HEADER(query);  
+               MYSQLI_PROFILER_EXPLAIN(mysql,query);   
+               MYSQLI_PROFILER_GETTIME;
+               if (mysql_real_query(mysql, query, query_len)){
+                       RETURN_FALSE;
+               }
+               MYSQLI_PROFILER_REPORTTIME;
+       }
+       else {
+               if (mysql_real_query(mysql, query, query_len)) {
+                       RETURN_FALSE;
+               }
        }
 
        if (!mysql_field_count(mysql)) {
@@ -133,6 +145,9 @@ PHP_FUNCTION(mysqli_query) {
        if (!result) {
                RETURN_FALSE;
        }       
+       if (MyG(profiler.active)) {
+               MYSQLI_PROFILER_REPORT_RESULT(result);
+       }
        MYSQLI_RETURN_RESOURCE(result, mysqli_result_class_entry);
 }
 /* }}} */
diff --git a/ext/mysqli/mysqli_profiler.c b/ext/mysqli/mysqli_profiler.c
new file mode 100644 (file)
index 0000000..8eddad3
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+  +----------------------------------------------------------------------+
+  | PHP Version 5                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.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.               |
+  +----------------------------------------------------------------------+
+  | Author: Georg Richter <georg@php.net>                                |
+  +----------------------------------------------------------------------+
+
+  $Id$ 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_mysqli.h"
+
+#define DIVIDER  "************************************************************"
+#define DIVIDER1 "------------------------------------------------------------"
+
+/* {{{ void php_mysqli_profiler_header(char *query) */
+void php_mysqli_profiler_header(char *query)
+{
+       printf("%s\n", DIVIDER);
+       printf("File: %s\nLine: %d\n", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C));
+       printf("Function: %s\n", get_active_function_name(TSRMLS_C));
+       if (query) {
+               printf("SQL: %s\n", query);
+       }
+}
+/* }}} */
+
+/* {{{ void php_mysqli_profiler_result(MYSQL_RES *) */
+void php_mysqli_profiler_result_info(MYSQL_RES *res)
+{
+       printf("%s\nRows returned: %d\n", DIVIDER1, mysql_num_rows(res));
+}
+/* }}} */
+
+/* {{{ void php_mysqli_profiler_explain(MYSQL *, char *) */
+void php_mysqli_profiler_explain(MYSQL *mysql, char *query)
+{
+       MYSQL_RES               *res;
+       MYSQL_ROW               row;
+       MYSQL_FIELD             *fields;
+       unsigned int    i;
+       char *newquery = (char *)emalloc(strlen(query) + 10);
+       sprintf (newquery, "EXPLAIN %s", query);
+
+       mysql_real_query(mysql, newquery, strlen(newquery));
+       efree (newquery);
+
+       if (mysql_errno(mysql)) {
+               printf ("%s\nError (%d): %s\n", DIVIDER1, mysql_errno(mysql), mysql_error(mysql));
+               return;
+       }
+
+       res = mysql_use_result(mysql);
+
+       printf ("%s\nEXPLAIN:\n", DIVIDER1);
+       fields = mysql_fetch_fields(res);
+       while ((row = mysql_fetch_row(res))) {
+               for (i=0; i < mysql_num_fields(res); i++) {
+                       printf ("%20s: %s\n", fields[i].name, row[i]);
+               } 
+               printf("\n");
+       }
+
+       mysql_free_result(res);
+       return;
+}
+/* }}} */
+
+/* {{{ void php_mysqli_profiler_elapsed_time() */
+void php_mysqli_profiler_elapsed_time()
+{
+       struct timeval  end, elapsed;
+
+       gettimeofday(&end, NULL);
+
+       elapsed.tv_sec = end.tv_sec - MyG(profiler.start.tv_sec);
+       elapsed.tv_usec = end.tv_usec - MyG(profiler.start.tv_usec);
+       if (elapsed.tv_usec < 0) {
+               --(elapsed.tv_sec);
+               elapsed.tv_usec = 1000000;
+       }               
+       printf("%s\nElapsed time: %3d.%06d seconds\n", DIVIDER1, elapsed.tv_sec, elapsed.tv_usec);
+}
+/* }}} */
+
+/* {{{ proto void mysqli_set_profiler_opt (bool profiler)
+*/
+PHP_FUNCTION(mysqli_set_profiler_opt)
+{ 
+       int flags;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) {
+               return;
+       }
+       MyG(profiler.active) = flags;
+       
+       return;
+}
+/* }}} */
+/*
+ * 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
+ */
index be3c67d439798a58eae23c621d1bf0dad1aab982..36424b3aa01046c267f04663d5f9daaea91c93e3 100644 (file)
 #undef LIST
 #endif
 
+#ifdef PHP_WIN32
+#include "win32/time.h"
+#else
+#include "sys/time.h"
+#endif
+
 #include <mysql.h>
 
 #ifndef PHP_MYSQLI_H
 #define PHP_MYSQLI_H
 
+#define MYSQLI_PR_TYPE_QUERY    0
+#define MYSQLI_PR_TYPE_PREPARE  1
+
+
 typedef struct {
        ulong           buflen;
        char            *buffer;
@@ -45,6 +55,18 @@ typedef struct {
        char            type;
 } STMT;
 
+typedef struct {
+       char            active;
+       struct timeval  start;
+       unsigned int    count[2];
+       ulong           min_row_val[2];
+       ulong           max_row_val[2];
+       ulong           row_val[2];
+       double          min_elapsed[2];
+       double          max_elapsed[2];
+       double          elapsed[2];
+} PROFILER;
+
 typedef struct _mysqli_object {
        zend_object zo;
        void *ptr;
@@ -71,6 +93,13 @@ extern function_entry mysqli_stmt_methods[];
 extern function_entry mysqli_result_methods[];
 extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int flag);
 extern void php_clear_stmt_bind(STMT *stmt);
+
+/* Profiler functions */
+extern void php_mysqli_profiler_result_info(MYSQL_RES *res);
+void php_mysqli_profiler_explain(MYSQL *mysql, char *query);
+void php_mysqli_profiler_header(char *query);
+void php_mysqli_profiler_elapsed_time();
+
 zend_class_entry *mysqli_link_class_entry;
 zend_class_entry *mysqli_stmt_class_entry;
 zend_class_entry *mysqli_result_class_entry;
@@ -153,8 +182,8 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML
 #define MYSQLI_BIND_SEND_DATA  4
 
 /* fetch types */
-#define FETCH_SIMPLE           0
-#define FETCH_RESULT           1
+#define FETCH_SIMPLE           1
+#define FETCH_RESULT           2
 
 PHP_MYSQLI_API void mysqli_register_link(zval *return_value, void *link TSRMLS_DC);
 PHP_MYSQLI_API void mysqli_register_stmt(zval *return_value, void *stmt TSRMLS_DC);
@@ -230,6 +259,7 @@ PHP_FUNCTION(mysqli_rpl_query_type);
 PHP_FUNCTION(mysqli_select_db);
 PHP_FUNCTION(mysqli_send_long_data);
 PHP_FUNCTION(mysqli_send_query);
+PHP_FUNCTION(mysqli_set_profiler_opt);
 PHP_FUNCTION(mysqli_slave_query);
 PHP_FUNCTION(mysqli_ssl_set);
 PHP_FUNCTION(mysqli_stat);
@@ -245,16 +275,17 @@ PHP_FUNCTION(mysqli_use_result);
 PHP_FUNCTION(mysqli_warning_count);
 
 ZEND_BEGIN_MODULE_GLOBALS(mysqli)
-       long default_link;
-       long num_links;
-       long max_links;
-       unsigned int default_port;
-       char *default_host;
-       char *default_user;
-       char *default_pw;
-       char *default_socket;
-       long error_no;
-       char *error_msg;
+       long            default_link;
+       long            num_links;
+       long            max_links;
+       unsigned int    default_port;
+       char            *default_host;
+       char            *default_user;
+       char            *default_pw;
+       char            *default_socket;
+       long            error_no;
+       char            *error_msg;
+       PROFILER        profiler;
 ZEND_END_MODULE_GLOBALS(mysqli)
 
 #ifdef ZTS
@@ -263,6 +294,18 @@ ZEND_END_MODULE_GLOBALS(mysqli)
 #define MyG(v) (mysqli_globals.v)
 #endif
 
+#define MYSQLI_PROFILER_GETTIME gettimeofday(&MyG(profiler.start), NULL)
+#define MYSQLI_PROFILER_REPORTTIME php_mysqli_profiler_elapsed_time()
+#define MYSQLI_PROFILER_HEADER(query) php_mysqli_profiler_header(query)
+#define MYSQLI_PROFILER_REPORT_RESULT(res) php_mysqli_profiler_result_info(res)
+#define MYSQLI_PROFILER_EXPLAIN(mysql,query) \
+if (!strncasecmp("select", Z_STRVAL_PP(query), 6)){ \
+       php_mysqli_profiler_explain(mysql,query); \
+       if (mysql_errno(mysql)) { \
+               RETURN_FALSE; \
+       } \
+}
+
 ZEND_EXTERN_MODULE_GLOBALS(mysqli);
 
 #endif /* PHP_MYSQLI.H */