diff options
author | Georg Richter <georg@php.net> | 2003-03-11 01:19:21 +0000 |
---|---|---|
committer | Georg Richter <georg@php.net> | 2003-03-11 01:19:21 +0000 |
commit | 7cf921a56f3e85af996a9d13b99d808c277a693e (patch) | |
tree | 1a514764d14e27983a37949be030ccc60fa50f53 | |
parent | febb535db08d96ff47c74b679a14afc6bd6b7906 (diff) | |
download | php-git-7cf921a56f3e85af996a9d13b99d808c277a693e.tar.gz |
profiler:
moved profiler stuff from php_mysql.h to separate include file
added port communication
added xml support for file and port output
-rw-r--r-- | ext/mysqli/mysqli.c | 27 | ||||
-rw-r--r-- | ext/mysqli/mysqli_api.c | 9 | ||||
-rw-r--r-- | ext/mysqli/mysqli_nonapi.c | 2 | ||||
-rw-r--r-- | ext/mysqli/mysqli_profiler.c | 260 | ||||
-rw-r--r-- | ext/mysqli/mysqli_profiler.h | 226 | ||||
-rw-r--r-- | ext/mysqli/mysqli_profiler_com.c | 98 | ||||
-rw-r--r-- | ext/mysqli/mysqli_profiler_com.h | 53 | ||||
-rw-r--r-- | ext/mysqli/php_mysqli.h | 131 |
8 files changed, 596 insertions, 210 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index d72b80b67c..ec014bb63b 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -30,12 +30,12 @@ #include "ext/standard/php_string.h" #include "php_mysqli.h" - #define MYSQLI_STORE_RESULT 0 #define MYSQLI_USE_RESULT 1 ZEND_DECLARE_MODULE_GLOBALS(mysqli) static zend_object_handlers mysqli_object_handlers; +PR_MAIN *prmain; /* {{{ php_clear_stmt_bind */ void php_clear_stmt_bind(STMT *stmt) @@ -79,9 +79,6 @@ static void mysqli_objects_dtor(void *object, zend_object_handle handle TSRMLS_D if (intern->zo.ce == mysqli_link_class_entry) { if (my_res && my_res->ptr) { mysql_close(my_res->ptr); - if (MyG(profiler)) { - php_mysqli_profiler_report(my_res->prinfo, 0); - } } } else if (intern->zo.ce == mysqli_stmt_class_entry) { /* stmt object */ if (my_res && my_res->ptr) { @@ -278,6 +275,12 @@ PHP_MINIT_FUNCTION(mysqli) /* bind blob support */ REGISTER_LONG_CONSTANT("MYSQLI_NEED_DATA", MYSQL_NEED_DATA, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_CS | CONST_PERSISTENT); + + /* profiler support */ + REGISTER_LONG_CONSTANT("MYSQLI_PR_REPORT_STDERR", 1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_PR_REPORT_PORT", 2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_PR_REPORT_FILE", 3, CONST_CS | CONST_PERSISTENT); + return SUCCESS; } /* }}} */ @@ -314,6 +317,18 @@ PHP_RSHUTDOWN_FUNCTION(mysqli) efree(MyG(error_msg)); } + if (MyG(profiler)) { + if (prmain->header.child) { + php_mysqli_profiler_report((PR_COMMON *)prmain, 0); + } + switch (prmain->mode) { + case MYSQLI_PR_REPORT_FILE: + fclose(prmain->fp); + efree(prmain->name); + break; + } + } + return SUCCESS; } /* }}} */ @@ -405,7 +420,9 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags } if (MyG(profiler)) { - MYSQLI_PROFILER_COMMAND_RETURNSTRING(prcommand, NULL); + char tmp[10]; + sprintf ((char *)&tmp,"row[%d]", mysql_num_fields(result)); + MYSQLI_PROFILER_COMMAND_RETURNSTRING(prcommand, tmp); prresult->fetched_rows++; } } diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index d03d43eae4..e0e4fc901d 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -48,7 +48,7 @@ PHP_FUNCTION(mysqli_affected_rows) MYSQLI_PROFILER_COMMAND_START(prcommand, prmysql); rc = mysql_affected_rows(mysql); - MYSQLI_PROFILER_COMMAND_RETURNLONG(prcommand, rc); + MYSQLI_PROFILER_COMMAND_RETURNLONG(prcommand, (long)rc); MYSQLI_RETURN_LONG_LONG(rc); } /* }}} */ @@ -491,14 +491,17 @@ PHP_FUNCTION(mysqli_data_seek) */ PHP_FUNCTION(mysqli_debug) { - char *debug; - int debug_len; + char *debug; + int debug_len; + PR_COMMAND *prcommand; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) { return; } + MYSQLI_PROFILER_COMMAND_START(prcommand, prmain); mysql_debug(debug); + MYSQLI_PROFILER_COMMAND_RETURNSTRING(prcommand, NULL); RETURN_TRUE; } /* }}} */ diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 2da3ded661..e87614acf3 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -78,7 +78,7 @@ PHP_FUNCTION(mysqli_connect) } if (MyG(profiler)) { - prmysql = (PR_MYSQL *)MYSQLI_PROFILER_NEW(NULL, MYSQLI_PR_MYSQL, 0); + prmysql = (PR_MYSQL *)MYSQLI_PROFILER_NEW(prmain, MYSQLI_PR_MYSQL, 0); php_mysqli_profiler_timediff(starttime, &prmysql->header.elapsedtime); MYSQLI_PROFILER_STARTTIME(prmysql); prmysql->hostname = estrdup(hostname); diff --git a/ext/mysqli/mysqli_profiler.c b/ext/mysqli/mysqli_profiler.c index 96ecd03769..97cfd86ce9 100644 --- a/ext/mysqli/mysqli_profiler.c +++ b/ext/mysqli/mysqli_profiler.c @@ -26,6 +26,7 @@ #include "php_ini.h" #include "ext/standard/info.h" #include "php_mysqli.h" +#include "mysqli_profiler_com.h" /* {{{ PR_COMMON *php_mysqli_profiler_new_object(PR_COMMON *parent, unsigned int type, unsigned int settime) */ PR_COMMON *php_mysqli_profiler_new_object(PR_COMMON *parent, unsigned int type, unsigned int settime) @@ -78,8 +79,9 @@ PR_COMMON *php_mysqli_profiler_new_object(PR_COMMON *parent, unsigned int type, int php_mysqli_profiler_explain(PR_EXPLAIN *explain, PR_HEADER *header, MYSQL *mysql, char *query) { MYSQL_RES *res; - MYSQL_ROW row; - unsigned int i; + unsigned int i,j; + MYSQL_FIELD *fields; + MYSQL_ROW row; char *newquery = (char *)emalloc(strlen(query) + 10); sprintf (newquery, "EXPLAIN %s", query); @@ -99,17 +101,23 @@ int php_mysqli_profiler_explain(PR_EXPLAIN *explain, PR_HEADER *header, MYSQL *m return 0; } - explain->exp_table = (char **)emalloc(sizeof(char *) * explain->exp_cnt); - explain->exp_type = (char **)emalloc(sizeof(char *) * explain->exp_cnt); - explain->exp_key = (char **)emalloc(sizeof(char *) * explain->exp_cnt); - explain->exp_rows = (ulong *)emalloc(sizeof(ulong) * explain->exp_cnt); + explain->columns = mysql_num_fields(res); + + explain->row = (PR_ROW *)emalloc(sizeof(PR_ROW) * explain->exp_cnt); + explain->fields = (char **)emalloc(sizeof(char *) * explain->columns); + + fields = mysql_fetch_fields(res); + + for (j=0; j < explain->columns; j++) { + explain->fields[j] = estrdup(fields[j].name); + } for (i=0; i < explain->exp_cnt; i++) { + explain->row[i].value = (char **)emalloc(sizeof(char *) * explain->columns); row = mysql_fetch_row(res); - explain->exp_table[i] = my_estrdup(row[2]); - explain->exp_type[i] = my_estrdup(row[3]); - explain->exp_key[i] = my_estrdup(row[4]); - explain->exp_rows[i] = atol(row[8]); + for (j=0; j < explain->columns; j++) { + explain->row[i].value[j] = my_estrdup(row[j]); + } } mysql_free_result(res); @@ -143,38 +151,38 @@ char *php_mysqli_profiler_indent(int i) } /* }}} */ -/* {{{ void php_mysqli_profiler_report_header(PR_HEADER, char *) */ +/* {{{ void php_mysqli_profiler_report_header(PR_HEADER, char *, char *) */ void php_mysqli_profiler_report_header(PR_HEADER header, char *ident) { + char buffer[8192]; switch (header.type) { case MYSQLI_PR_MYSQL: - printf("%s[Connection]\n", ident); php_mysqli_profiler_timediff(header.starttime, &header.lifetime); break; - case MYSQLI_PR_QUERY: - printf("%s[Query]\n", ident); - break; case MYSQLI_PR_STMT: - printf("%s[Statement]\n", ident); php_mysqli_profiler_timediff(header.starttime, &header.lifetime); break; case MYSQLI_PR_RESULT: - printf("%s[Resultset]\n", ident); php_mysqli_profiler_timediff(header.starttime, &header.lifetime); break; - case MYSQLI_PR_COMMAND: - printf("%s[Command]\n", ident); - break; } - printf ("%sFunction: %s\n", ident, header.functionname); - printf ("%sFile: %s\n", ident, header.filename); - printf ("%sLine: %d\n", ident, header.lineno); - printf ("%sExecution time: %ld.%06ld\n", ident, header.elapsedtime.tv_sec, header.elapsedtime.tv_usec); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "name", header.functionname); + + MYSQLI_PROFILER_ADD_STARTTAG(buffer, "fileinfo",0); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "name", header.filename); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "line", header.lineno); + MYSQLI_PROFILER_ADD_ENDTAG(buffer, "fileinfo"); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, "times",0); + MYSQLI_PROFILER_ADD_ATTR_TIME(buffer, "execution_time", header.elapsedtime.tv_sec, header.elapsedtime.tv_usec); if (header.lifetime.tv_sec + header.lifetime.tv_usec) { - printf ("%sLife time: %ld.%06ld\n", ident, header.lifetime.tv_sec, header.lifetime.tv_usec); + MYSQLI_PROFILER_ADD_ATTR_TIME(buffer, "life_time", header.lifetime.tv_sec, header.lifetime.tv_usec); } + MYSQLI_PROFILER_ADD_ENDTAG(buffer, "times"); if (header.error) { - printf("%sError: %s (%ld)\n", ident, header.errormsg, header.error); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, "errors",0); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "errno", header.error); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "errmsg", header.errormsg); + MYSQLI_PROFILER_ADD_ENDTAG(buffer, "errors"); } /* free header */ @@ -184,40 +192,33 @@ void php_mysqli_profiler_report_header(PR_HEADER header, char *ident) } /* }}} */ -/* {{{ void php_mysqli_profiler_report_explain(PR_EXPLAIN, char *) */ +/* {{{ void php_mysqli_profiler_report_explain(PR_EXPLAIN, char *, char *) */ void php_mysqli_profiler_report_explain(PR_EXPLAIN explain, char *ident) { - int i; + int i, j; + char buffer[8192]; if (explain.query) { - printf("%sQuery: %s\n", ident, explain.query); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "query_string", explain.query); } if (explain.exp_cnt) { - printf("%sTable(s):", ident); - for (i=0; i < explain.exp_cnt; i++) { - printf(" %s%c", explain.exp_table[i], (i == explain.exp_cnt - 1) ? '\n' : ','); - my_efree(explain.exp_table[i]); - } - printf("%sJoin-Types(s):", ident); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, "explain", 1); for (i=0; i < explain.exp_cnt; i++) { - printf(" %s%c", explain.exp_type[i], (i == explain.exp_cnt - 1) ? '\n' : ','); - my_efree(explain.exp_type[i]); + for (j=0; j < explain.columns; j++) { + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, explain.fields[j], explain.row[i].value[j]); + my_efree(explain.row[i].value[j]); + } + efree(explain.row[i].value); } - printf("%sKey(s):", ident); - for (i=0; i < explain.exp_cnt; i++) { - printf(" %s%c", explain.exp_key[i], (i == explain.exp_cnt - 1) ? '\n' : ','); - my_efree(explain.exp_key[i]); - } - printf("%sRow(s):", ident); - for (i=0; i < explain.exp_cnt; i++) { - printf(" %ld%c", explain.exp_rows[i], (i == explain.exp_cnt - 1) ? '\n' : ','); - } - my_efree(explain.exp_table); - my_efree(explain.exp_type); - my_efree(explain.exp_key); - my_efree(explain.exp_rows); + MYSQLI_PROFILER_ADD_ENDTAG(buffer, "explain"); + } + efree(explain.row); + for (j=0; j < explain.columns; j++) { + my_efree(explain.fields[j]); } + efree(explain.fields); + /* free explain */ my_efree(explain.query); } @@ -226,17 +227,20 @@ void php_mysqli_profiler_report_explain(PR_EXPLAIN explain, char *ident) /* {{{ php_mysqli_profiler_report_mysql(PR_MYSQL *, int) */ void php_mysqli_profiler_report_mysql(PR_MYSQL *prmysql, int depth) { - char *ident = php_mysqli_profiler_indent(depth); + char *ident = php_mysqli_profiler_indent(depth); + char buffer[8192]; php_mysqli_profiler_report_header(prmysql->header, ident); - printf ("%sHost: %s\n", ident, prmysql->hostname); - printf ("%sUser: %s\n", ident, prmysql->username); - printf ("%sThread-id: %d\n", ident, prmysql->thread_id); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "hostname", prmysql->hostname); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "user", prmysql->username); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "thread_id", prmysql->thread_id); + if (!prmysql->closed) { - printf ("%sWarning: connection wasn't closed by mysqli_close()\n", ident); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, "warnings",0); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "warning", "connection wasn't closed by mysqli_close()"); + MYSQLI_PROFILER_ADD_ENDTAG(buffer, "warnings"); } - printf("\n"); my_efree(prmysql->hostname); my_efree(prmysql->username); @@ -248,20 +252,19 @@ void php_mysqli_profiler_report_mysql(PR_MYSQL *prmysql, int depth) /* {{{ void php_mysqli_profiler_report_query(PR_QUERY *, int) */ void php_mysqli_profiler_report_query(PR_QUERY *prquery, int depth) { - char *ident = php_mysqli_profiler_indent(depth); + char buffer[8192]; + char *ident = php_mysqli_profiler_indent(depth); php_mysqli_profiler_report_header(prquery->header, ident); php_mysqli_profiler_report_explain(prquery->explain, ident); if (prquery->affectedrows > 0) { - printf ("%saffected rows: %ld\n", ident, prquery->affectedrows); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "affected_rows", prquery->affectedrows); } if (prquery->insertid) { - printf ("%sinsert id: %ld\n", ident, prquery->insertid); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "insert_id", prquery->insertid); } - - printf("\n"); efree(ident); } /* }}} */ @@ -269,12 +272,15 @@ void php_mysqli_profiler_report_query(PR_QUERY *prquery, int depth) /* {{{ void php_mysqli_profiler_report_stmt(PR_STMT *, int) */ void php_mysqli_profiler_report_stmt(PR_STMT *prstmt, int depth) { - char *ident = php_mysqli_profiler_indent(depth); + char *ident = php_mysqli_profiler_indent(depth); + char buffer[8192]; + buffer[0] = '\0'; php_mysqli_profiler_report_header(prstmt->header, ident); php_mysqli_profiler_report_explain(prstmt->explain, ident); printf("\n"); + MYSQLI_PROFILER_OUT(buffer); efree(ident); } /* }}} */ @@ -282,17 +288,25 @@ void php_mysqli_profiler_report_stmt(PR_STMT *prstmt, int depth) /* {{{ void php_mysqli_profiler_report_result(PR_RESULT *, int) */ void php_mysqli_profiler_report_result(PR_RESULT *prresult, int depth) { - char *ident = php_mysqli_profiler_indent(depth); + char *ident = php_mysqli_profiler_indent(depth); + char buffer[8192]; + buffer[0] = '\0'; php_mysqli_profiler_report_header(prresult->header, ident); - printf ("%sColumns: %d\n", ident, prresult->columns); - printf ("%sRows: %ld\n", ident, prresult->rows); - printf ("%sFetched rows: %ld\n", ident, prresult->fetched_rows); - if (!prresult->closed) { - printf ("%sWarning: resultset wasn't closed by mysqli_free_result()\n", ident); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "columns", prresult->columns); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "rows", prresult->rows); + MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, "fetched_rows", prresult->fetched_rows); + if (!prresult->closed || prresult->fetched_rows != prresult->rows) { + MYSQLI_PROFILER_ADD_STARTTAG(buffer, "warnings",0); + if (!prresult->closed) { + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "warning", "resultset wasn't closed by mysqli_free_result()"); + } + if (prresult->fetched_rows != prresult->rows) { + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "warning", "Not all rows from resultset were fetched."); + } + MYSQLI_PROFILER_ADD_ENDTAG(buffer, "warnings"); } - printf("\n"); efree(ident); } /* }}} */ @@ -300,14 +314,16 @@ void php_mysqli_profiler_report_result(PR_RESULT *prresult, int depth) /* {{{ void php_mysqli_profiler_report_command(PR_COMMAND *, int) */ void php_mysqli_profiler_report_command(PR_COMMAND *prcommand, int depth) { - char *ident = php_mysqli_profiler_indent(depth); + char *ident = php_mysqli_profiler_indent(depth); + char buffer[8192]; + buffer[0] = '\0'; php_mysqli_profiler_report_header(prcommand->header, ident); + if (prcommand->returnvalue) { - printf("%sReturnvalue: %s\n", ident, prcommand->returnvalue); + MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, "return_value", prcommand->returnvalue); efree(prcommand->returnvalue); } - printf("\n"); efree(ident); } /* }}} */ @@ -317,23 +333,42 @@ void php_mysqli_profiler_report(PR_COMMON *current, int depth) { PR_COMMON *child; PR_COMMON *next; + char buffer[8192]; + char tag[50]; + char *ident = php_mysqli_profiler_indent(depth); + + buffer[0] = '\0'; + switch (current->header.type) { + case MYSQLI_PR_MAIN: + { + MYSQLI_PROFILER_ADD_STARTTAG(buffer,"?xml version=\"1.0\" ?", 0); + sprintf((char *)&tag, "profilerinfo source='PHP5' version='%2.1f'", MYSQLI_PROFILER_VERSION); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, tag, 0); + strcpy (tag, "profilerinfo"); + } + break; case MYSQLI_PR_MYSQL: { PR_MYSQL *prmysql = (PR_MYSQL *)current; + strcpy(tag, "connection"); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, tag, 1); php_mysqli_profiler_report_mysql(prmysql, depth); } break; case MYSQLI_PR_COMMAND: { PR_COMMAND *prcommand = (PR_COMMAND *)current; - child = NULL; + strcpy(tag, "command"); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, tag, 1); php_mysqli_profiler_report_command(prcommand, depth); } break; case MYSQLI_PR_RESULT: { PR_RESULT *prresult = (PR_RESULT *)current; + strcpy(tag, "resultset"); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, tag, 1); php_mysqli_profiler_report_result(prresult, depth); } break; @@ -341,6 +376,8 @@ void php_mysqli_profiler_report(PR_COMMON *current, int depth) case MYSQLI_PR_STMT_RESULT: { PR_STMT *prstmt = (PR_STMT *)current; + strcpy(tag, "statement"); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, tag, 1); php_mysqli_profiler_report_stmt(prstmt, depth); } break; @@ -348,6 +385,8 @@ void php_mysqli_profiler_report(PR_COMMON *current, int depth) case MYSQLI_PR_QUERY_RESULT: { PR_QUERY *prquery = (PR_QUERY *)current; + strcpy(tag, "query"); + MYSQLI_PROFILER_ADD_STARTTAG(buffer, tag, 1); php_mysqli_profiler_report_query(prquery, depth); } break; @@ -357,28 +396,91 @@ void php_mysqli_profiler_report(PR_COMMON *current, int depth) php_mysqli_profiler_report(child, depth+1); } + MYSQLI_PROFILER_ADD_ENDTAG(buffer, tag); next = (current->header.next) ? current->header.next : NULL; if (next) { php_mysqli_profiler_report(next, depth); } + + if (current->header.type == MYSQLI_PR_MAIN) { + PR_MAIN *prmain = (PR_MAIN *)current; + my_efree(prmain->name); + } efree(current); + efree(ident); return; } /* }}} */ -/* {{{ proto void mysqli_profiler (bool profiler) +/* {{{ proto bool mysqli_profiler (int flags, char *info, int port) */ PHP_FUNCTION(mysqli_profiler) { - int flags; + int flag; + char *name; + int name_len = 0, port = 0; + int connection; + + if (MyG(profiler)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Profiler was already started."); + RETURN_FALSE; + } - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|sl", &flag, &name, &name_len, &port) == FAILURE) { return; } - MyG(profiler) = flags; - - return; + + switch (flag) { + case MYSQLI_PR_REPORT_STDERR: + prmain = ecalloc(1, sizeof(PR_MAIN)); + prmain->mode = flag; + break; + case MYSQLI_PR_REPORT_PORT: + if (!name_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hostname not specified."); + RETURN_FALSE; + } + if (!port) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Portnumber not specified."); + RETURN_FALSE; + } + if (!(connection = php_mysqli_create_socket(name, port))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to host %s on port %d, name, port"); + RETURN_FALSE; + } + prmain = ecalloc(1, sizeof(PR_MAIN)); + prmain->mode = flag; + prmain->port = port; + prmain->name = my_estrdup(name); + prmain->connection = connection; + break; + case MYSQLI_PR_REPORT_FILE: + if (!name_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename not specified."); + RETURN_FALSE; + } + prmain = ecalloc(1, sizeof(PR_MAIN)); + if (!(prmain->fp = fopen(name, "w"))){ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't write to file %s.", name); + efree(prmain); + RETURN_FALSE; + } + prmain->mode = flag; + prmain->name = my_estrdup(name); + + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported flag: %d", flag); + RETURN_FALSE; + } + + +/* PR_SSEND(port,"<application>"); + php_mysqli_close_socket(prmain.connection); +*/ + MyG(profiler) = flag; + RETURN_TRUE; } /* }}} */ /* diff --git a/ext/mysqli/mysqli_profiler.h b/ext/mysqli/mysqli_profiler.h new file mode 100644 index 0000000000..b4d058cd66 --- /dev/null +++ b/ext/mysqli/mysqli_profiler.h @@ -0,0 +1,226 @@ +/* + +----------------------------------------------------------------------+ + | 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> | + +----------------------------------------------------------------------+ +*/ + +#ifndef __HAVE_MYSQLI_PROFILER_H__ +#define __HAVE_MYSQLI_PROFILER_H__ + +#ifdef PHP_WIN32 +#include "win32/time.h" +#else +#include "sys/time.h" +#endif + +#define MYSQLI_PROFILER_VERSION 0.9 + +/* common profiler header struct */ +typedef struct { + unsigned int type; + void *child; + void *next; + char *filename; + unsigned int lineno; + char *functionname; + struct timeval starttime; + struct timeval elapsedtime; + struct timeval lifetime; + char *errormsg; + ulong error; +} PR_HEADER; + +typedef struct { + char **value; +} PR_ROW; + +/* explain output */ +typedef struct { + char *query; + unsigned int exp_cnt; + unsigned int columns; + char **fields; + PR_ROW *row; +} PR_EXPLAIN; + +/* main profiler */ +typedef struct { + PR_HEADER header; + unsigned int mode; + char *name; + int port; + char *info; + int connection; + FILE *fp; +} PR_MAIN; + +/* common */ +typedef struct { + PR_HEADER header; +} PR_COMMON; + +/* connection */ +typedef struct { + PR_HEADER header; + unsigned int thread_id; + char *hostname; + char *username; + unsigned int closed; +} PR_MYSQL; + +/* resultset */ +typedef struct { + PR_HEADER header; + unsigned int columns; + ulong rows; + ulong fields; + ulong fetched_rows; + unsigned int closed; +} PR_RESULT; + +/* command */ +/* TODO: return values */ +typedef struct { + PR_HEADER header; + ulong returntype; + char *returnvalue; +} PR_COMMAND; + +/* query */ +typedef struct { + PR_HEADER header; + PR_EXPLAIN explain; + ulong affectedrows; + ulong insertid; +} PR_QUERY; + +/* statement */ +typedef struct { + PR_HEADER header; + PR_EXPLAIN explain; + unsigned int param_cnt; + unsigned int field_cnt; +} PR_STMT; + +/* Profiler protofypes */ +extern void php_mysqli_profiler_report(PR_COMMON *, int); +extern PR_COMMON *php_mysqli_profiler_new_object(PR_COMMON *parent, unsigned int type, unsigned int settime); +extern void php_mysqli_profiler_result_info(MYSQL_RES *res); +extern int php_mysqli_profiler_explain(PR_EXPLAIN *explain, PR_HEADER *header, MYSQL *mysql, char *query); +extern void php_mysqli_profiler_timediff(struct timeval start, struct timeval *elapsed); +extern PR_MAIN *prmain; + +/*** PROFILER MODES ***/ +#define MYSQLI_PR_REPORT_STDERR 1 +#define MYSQLI_PR_REPORT_PORT 2 +#define MYSQLI_PR_REPORT_FILE 3 + +/*** PROFILER CONSTANTS ***/ +#define MYSQLI_PR_MAIN 0 +#define MYSQLI_PR_MYSQL 1 +#define MYSQLI_PR_QUERY 2 +#define MYSQLI_PR_QUERY_RESULT 3 +#define MYSQLI_PR_STMT 4 +#define MYSQLI_PR_STMT_RESULT 5 +#define MYSQLI_PR_RESULT 6 + +/*** PROFILER MACROS ***/ +#define MYSQLI_PROFILER_STARTTIME(ptr) gettimeofday(&ptr##->header.starttime, NULL) +#define MYSQLI_PROFILER_ELAPSEDTIME(ptr) php_mysqli_profiler_timediff(ptr##->header.starttime, &ptr##->header.elapsedtime) +#define MYSQLI_PROFILER_LIFETIME(ptr) php_mysqli_profiler_timediff((ptr)->starttime, &(ptr)->lifetime) +#define MYSQLI_PROFILER_NEW(parent, type, time) php_mysqli_profiler_new_object((PR_COMMON *)parent, type, time) +#define MYSQLI_PROFILER_COMMAND_START(cmd,parent)\ +if (MyG(profiler))\ +{\ + cmd = (PR_COMMAND *)php_mysqli_profiler_new_object((PR_COMMON *)parent, MYSQLI_PR_COMMAND,1);\ +} + +#define MYSQLI_PROFILER_COMMAND_RETURNLONG(cmd, value)\ +if (MyG(profiler))\ +{\ + char tmp[30];\ + sprintf ((char *)&tmp, "%ld", value);\ + MYSQLI_PROFILER_ELAPSEDTIME(cmd);\ + cmd##->returnvalue = my_estrdup(tmp);\ +} + +#define MYSQLI_PROFILER_COMMAND_RETURNSTRING(cmd, value)\ +if (MyG(profiler))\ +{\ + MYSQLI_PROFILER_ELAPSEDTIME(cmd);\ + cmd##->returnvalue = my_estrdup(value);\ +} +#define MYSQLI_PROFILER_EXPLAIN(explain,header,mysql,query) php_mysqli_profiler_explain(explain,header, mysql, query) + +#define MYSQLI_PROFILER_OUT(buffer)\ + switch (prmain->mode) {\ + case MYSQLI_PR_REPORT_STDERR:\ + fprintf(stderr, "%s", buffer);\ + break;\ + case MYSQLI_PR_REPORT_FILE:\ + fprintf(prmain->fp, "%s", buffer);\ + break;\ + case MYSQLI_PR_REPORT_PORT:\ + PR_SSEND(prmain->port,buffer);\ + break;\ + }\ + buffer[0] = '\0'; + +#define MYSQLI_PROFILER_ADD_STARTTAG(buffer, str, out)\ + if (prmain->mode == MYSQLI_PR_REPORT_STDERR) {\ + if (out) { \ + sprintf((char *)&buffer, "%s[%s]\n", ident, str);\ + } \ + }\ + else {\ + sprintf((char *)&buffer, "<%s>\n", str);\ + }\ + MYSQLI_PROFILER_OUT(buffer); + +#define MYSQLI_PROFILER_ADD_ATTR_STRING(buffer, tag, value)\ + if (prmain->mode == MYSQLI_PR_REPORT_STDERR) {\ + sprintf((char *)&buffer, "%s%s: %s\n", ident, tag, value);\ + }\ + else {\ + sprintf((char *)&buffer, "<%s>%s</%s>\n", tag, value, tag);\ + }\ + MYSQLI_PROFILER_OUT(buffer); + +#define MYSQLI_PROFILER_ADD_ATTR_LONG(buffer, tag, value)\ + if (prmain->mode == MYSQLI_PR_REPORT_STDERR) {\ + sprintf((char *)&buffer, "%s%s: %ld\n", ident, tag, (long)value);\ + }\ + else {\ + sprintf((char *)&buffer, "<%s>%ld</%s>\n", tag, (long)value, tag);\ + }\ + MYSQLI_PROFILER_OUT(buffer); + +#define MYSQLI_PROFILER_ADD_ATTR_TIME(buffer, tag, sec, usec)\ + if (prmain->mode == MYSQLI_PR_REPORT_STDERR) {\ + sprintf((char *)&buffer, "%s%s: %ld.%06ld\n", ident, tag, sec, usec);\ + }\ + else {\ + sprintf((char *)&buffer, "<%s>%ld.%06ld</%s>\n", tag, sec, usec, tag);\ + }\ + MYSQLI_PROFILER_OUT(buffer); + +#define MYSQLI_PROFILER_ADD_ENDTAG(buffer, tag)\ + if (prmain->mode == MYSQLI_PR_REPORT_STDERR) {\ + fprintf(stderr, "\n"); \ + } else { \ + sprintf((char *)&buffer, "</%s>\n", tag);\ + }\ + MYSQLI_PROFILER_OUT(buffer); +#endif diff --git a/ext/mysqli/mysqli_profiler_com.c b/ext/mysqli/mysqli_profiler_com.c new file mode 100644 index 0000000000..8a4f18d2d9 --- /dev/null +++ b/ext/mysqli/mysqli_profiler_com.c @@ -0,0 +1,98 @@ +/* + +----------------------------------------------------------------------+ + | 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> | + +----------------------------------------------------------------------+ +*/ + +#include <string.h> +#include <sys/types.h> +#include <errno.h> +#ifndef PHP_WIN32 +#include <unistd.h> +#endif + +#ifdef PHP_WIN32 +# include <winsock.h> +# include <process.h> +# include <direct.h> +# include "win32/time.h" +#define PATH_MAX MAX_PATH +#else +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "mysqli_profiler_com.h" + +#ifdef PHP_WIN32 +int inet_aton(const char *cp, struct in_addr *inp) +{ + inp->s_addr = inet_addr(cp); + if (inp->s_addr == INADDR_NONE) { + return 0; + } + return 1; +} +#endif + +/* + * Converts a host name to an IP address. */ +static int lookup_hostname (const char *addr, struct in_addr *in) +{ + struct hostent *host_info; + + if (!inet_aton(addr, in)) { + host_info = gethostbyname(addr); + if (host_info == 0) { + /* Error: unknown host */ + return -1; + } + *in = *((struct in_addr *) host_info->h_addr); + } + return 0; +} +/* }}} */ + +int php_mysqli_create_socket(const char *hostname, int dport) +{ + struct sockaddr_in address; + int err = -1; + int sockfd; + + memset(&address, 0, sizeof(address)); + lookup_hostname(hostname, &address.sin_addr); + address.sin_family = AF_INET; + address.sin_port = htons((unsigned short)dport); + + sockfd = socket(address.sin_family, SOCK_STREAM, 0); + if (sockfd == SOCK_ERR) { + return -1; + } + while ((err = connect(sockfd, (struct sockaddr *) &address, + sizeof(address))) == SOCK_ERR && errno == EAGAIN); + + if (err < 0) { + PR_SCLOSE(sockfd); + return -1; + } + return sockfd; +} + +void php_mysqli_close_socket(int socket) +{ + PR_SCLOSE(socket); +} diff --git a/ext/mysqli/mysqli_profiler_com.h b/ext/mysqli/mysqli_profiler_com.h new file mode 100644 index 0000000000..0ea7f4fbc8 --- /dev/null +++ b/ext/mysqli/mysqli_profiler_com.h @@ -0,0 +1,53 @@ +/* + +----------------------------------------------------------------------+ + | 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> | + +----------------------------------------------------------------------+ +*/ + +#ifndef __HAVE_MYSQLI_PROFILER_COM_H__ +#define __HAVE_MYSQLI_PROFILER_COM_H__ + +#ifdef PHP_WIN32 +int inet_aton(const char *cp, struct in_addr *inp); +#endif + +#if WIN32|WINNT +# define SOCK_ERR INVALID_SOCKET +# define SOCK_CONN_ERR SOCKET_ERROR +# define SOCK_RECV_ERR SOCKET_ERROR +#else +# define SOCK_ERR -1 +# define SOCK_CONN_ERR -1 +# define SOCK_RECV_ERR -1 +#endif + +#if WIN32|WINNT +#define PR_SREAD(a,b,c) recv(a,b,c,0) +#define PR_SCLOSE(a) closesocket(a) +#define PR_SSENDL(a,b,c) send(a,b,c,0) +#define PR_SSEND(a,b) send(a,b,strlen(b),0) +#else +#define PR_SREAD(a,b,c) read(a,b,c) +#define PR_SCLOSE(a) close(a) +#define PR_SSENDL(a,b,c) write(a,b,c) +#define PR_SSEND(a,b) write(a,b,strlen(b)) +#endif + +/* function prototypes */ +int php_mysqli_create_socket(const char *hostname, int dport); +void php_mysqli_close_socket(int socket); + +#endif + diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index 5387e6c889..c823e64527 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -25,13 +25,8 @@ #undef LIST #endif -#ifdef PHP_WIN32 -#include "win32/time.h" -#else -#include "sys/time.h" -#endif - #include <mysql.h> +#include "mysqli_profiler.h" #ifndef PHP_MYSQLI_H #define PHP_MYSQLI_H @@ -57,92 +52,19 @@ typedef struct { void *ptr; /* resource: (mysql, result, stmt) */ } MYSQLI_RESOURCE; -/* common profiler header struct */ - -typedef struct { - unsigned int type; - void *child; - void *next; - char *filename; - unsigned int lineno; - char *functionname; - struct timeval starttime; - struct timeval elapsedtime; - struct timeval lifetime; - char *errormsg; - ulong error; -} PR_HEADER; - -/* explain output */ -typedef struct { - char *query; - unsigned int exp_cnt; - char **exp_table; - char **exp_type; - char **exp_key; - ulong *exp_rows; -} PR_EXPLAIN; - -/* common */ -typedef struct { - PR_HEADER header; -} PR_COMMON; - -/* connection */ -typedef struct { - PR_HEADER header; - unsigned int thread_id; - char *hostname; - char *username; - unsigned int closed; -} PR_MYSQL; - -/* resultset */ -typedef struct { - PR_HEADER header; - unsigned int columns; - ulong rows; - ulong fields; - ulong fetched_rows; - unsigned int closed; -} PR_RESULT; - -/* command */ -/* TODO: return values */ -typedef struct { - PR_HEADER header; - ulong returntype; - void *returnvalue; -} PR_COMMAND; - -/* query */ -typedef struct { - PR_HEADER header; - PR_EXPLAIN explain; - ulong affectedrows; - ulong insertid; -} PR_QUERY; - -/* statement */ -typedef struct { - PR_HEADER header; - PR_EXPLAIN explain; - unsigned int param_cnt; - unsigned int field_cnt; -} PR_STMT; - typedef struct _mysqli_object { zend_object zo; void *ptr; } mysqli_object; /* extends zend_object */ -#define MYSQLI_PR_MYSQL 0 -#define MYSQLI_PR_QUERY 1 -#define MYSQLI_PR_QUERY_RESULT 2 -#define MYSQLI_PR_STMT 3 -#define MYSQLI_PR_STMT_RESULT 4 -#define MYSQLI_PR_RESULT 5 -#define MYSQLI_PR_COMMAND 6 +#define MYSQLI_PR_MAIN 0 +#define MYSQLI_PR_MYSQL 1 +#define MYSQLI_PR_QUERY 2 +#define MYSQLI_PR_QUERY_RESULT 3 +#define MYSQLI_PR_STMT 4 +#define MYSQLI_PR_STMT_RESULT 5 +#define MYSQLI_PR_RESULT 6 +#define MYSQLI_PR_COMMAND 7 #define phpext_mysqli_ptr &mysqli_module_entry @@ -167,13 +89,6 @@ 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_report(PR_COMMON *, int); -extern PR_COMMON *php_mysqli_profiler_new_object(PR_COMMON *parent, unsigned int type, unsigned int settime); -extern void php_mysqli_profiler_result_info(MYSQL_RES *res); -extern int php_mysqli_profiler_explain(PR_EXPLAIN *explain, PR_HEADER *header, MYSQL *mysql, char *query); -extern void php_mysqli_profiler_timediff(struct timeval start, struct timeval *elapsed); - zend_class_entry *mysqli_link_class_entry; zend_class_entry *mysqli_stmt_class_entry; zend_class_entry *mysqli_result_class_entry; @@ -375,34 +290,6 @@ ZEND_END_MODULE_GLOBALS(mysqli) #define my_estrdup(x) (x) ? estrdup(x) : NULL #define my_efree(x) if (x) efree(x) -/****** PROFILER MACROS *******/ -#define MYSQLI_PROFILER_STARTTIME(ptr) gettimeofday(&ptr##->header.starttime, NULL) -#define MYSQLI_PROFILER_ELAPSEDTIME(ptr) php_mysqli_profiler_timediff(ptr##->header.starttime, &ptr##->header.elapsedtime) -#define MYSQLI_PROFILER_LIFETIME(ptr) php_mysqli_profiler_timediff((ptr)->starttime, &(ptr)->lifetime) - -#define MYSQLI_PROFILER_NEW(parent, type, time) php_mysqli_profiler_new_object((PR_COMMON *)parent, type, time) -#define MYSQLI_PROFILER_COMMAND_START(cmd,parent)\ -if (MyG(profiler))\ -{\ - cmd = (PR_COMMAND *)php_mysqli_profiler_new_object((PR_COMMON *)parent, MYSQLI_PR_COMMAND,1);\ -} -#define MYSQLI_PROFILER_COMMAND_RETURNLONG(cmd, value)\ -if (MyG(profiler))\ -{\ - char tmp[30];\ - sprintf ((char *)&tmp, "%ld", value);\ - MYSQLI_PROFILER_ELAPSEDTIME(cmd);\ - cmd##->returnvalue = my_estrdup(tmp);\ -} -#define MYSQLI_PROFILER_COMMAND_RETURNSTRING(cmd, value)\ -if (MyG(profiler))\ -{\ - MYSQLI_PROFILER_ELAPSEDTIME(cmd);\ - cmd##->returnvalue = my_estrdup(value);\ -} -#define MYSQLI_PROFILER_EXPLAIN(explain,header,mysql,query) php_mysqli_profiler_explain(explain,header, mysql, query) - - ZEND_EXTERN_MODULE_GLOBALS(mysqli); #endif /* PHP_MYSQLI.H */ |