PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - pdo_mysql - mysql_driver.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 283
Code covered: 92.2 % Executed lines: 261
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | PHP Version 6                                                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :   +----------------------------------------------------------------------+
       7                 :   | This source file is subject to version 3.01 of the PHP license,      |
       8                 :   | that is bundled with this package in the file LICENSE, and is        |
       9                 :   | available through the world-wide-web at the following url:           |
      10                 :   | http://www.php.net/license/3_01.txt                                  |
      11                 :   | If you did not receive a copy of the PHP license and are unable to   |
      12                 :   | obtain it through the world-wide-web, please send a note to          |
      13                 :   | license@php.net so we can mail you a copy immediately.               |
      14                 :   +----------------------------------------------------------------------+
      15                 :   | Author: George Schlossnagle <george@omniti.com>                      |
      16                 :   |         Wez Furlong <wez@php.net>                                    |
      17                 :   |         Johannes Schlueter <johannes@mysql.com>                      |
      18                 :   +----------------------------------------------------------------------+
      19                 : */
      20                 : 
      21                 : /* $Id: mysql_driver.c 288583 2009-09-22 15:31:35Z uw $ */
      22                 : 
      23                 : #ifdef HAVE_CONFIG_H
      24                 : #include "config.h"
      25                 : #endif
      26                 : 
      27                 : #include "php.h"
      28                 : #include "php_ini.h"
      29                 : #include "ext/standard/info.h"
      30                 : #include "pdo/php_pdo.h"
      31                 : #include "pdo/php_pdo_driver.h"
      32                 : #include "php_pdo_mysql.h"
      33                 : #include "php_pdo_mysql_int.h"
      34                 : #ifndef PDO_USE_MYSQLND
      35                 : #include <mysqld_error.h>
      36                 : #endif
      37                 : #include "zend_exceptions.h"
      38                 : 
      39                 : #if PDO_USE_MYSQLND
      40                 : #       define pdo_mysql_init(persistent) mysqlnd_init(persistent)
      41                 : #else
      42                 : #       define pdo_mysql_init(persistent) mysql_init(NULL)
      43                 : #endif
      44                 : 
      45                 : #if !HAVE_MYSQL_SQLSTATE && !PDO_USE_MYSQLND
      46                 : static const char *pdo_mysql_get_sqlstate(unsigned int my_errno) { /* {{{ */
      47                 :         switch (my_errno) {
      48                 :                 /* import auto-generated case: code */
      49                 : #include "php_pdo_mysql_sqlstate.h"
      50                 :         default: return "HY000";
      51                 :         }
      52                 : }
      53                 : /* }}} */
      54                 : #endif
      55                 : 
      56                 : /* {{{ _pdo_mysql_error */
      57                 : int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */
      58             611 : {
      59             611 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
      60                 :         pdo_error_type *pdo_err; 
      61                 :         pdo_mysql_error_info *einfo;
      62             611 :         pdo_mysql_stmt *S = NULL;
      63                 : 
      64             611 :         PDO_DBG_ENTER("_pdo_mysql_error");
      65             611 :         PDO_DBG_INF_FMT("file=%s line=%d", file, line);
      66             611 :         if (stmt) {
      67              31 :                 S = (pdo_mysql_stmt*)stmt->driver_data;
      68              31 :                 pdo_err = &stmt->error_code;
      69              31 :                 einfo   = &S->einfo;
      70                 :         } else {
      71             580 :                 pdo_err = &dbh->error_code;
      72             580 :                 einfo   = &H->einfo;
      73                 :         }
      74                 : 
      75                 : #if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
      76             614 :         if (S && S->stmt) {
      77               3 :                 einfo->errcode = mysql_stmt_errno(S->stmt);
      78                 :         }
      79                 :         else
      80                 : #endif
      81                 :         {
      82             608 :                 einfo->errcode = mysql_errno(H->server);
      83                 :         }
      84                 : 
      85             611 :         einfo->file = file;
      86             611 :         einfo->line = line;
      87                 : 
      88             611 :         if (einfo->errmsg) {
      89             355 :                 pefree(einfo->errmsg, dbh->is_persistent);
      90             355 :                 einfo->errmsg = NULL;
      91                 :         }
      92                 : 
      93             611 :         if (einfo->errcode) {
      94             601 :                 if (einfo->errcode == 2014) {
      95               8 :                         einfo->errmsg = pestrdup(
      96                 :                                 "Cannot execute queries while other unbuffered queries are active.  "
      97                 :                                 "Consider using PDOStatement::fetchAll().  Alternatively, if your code "
      98                 :                                 "is only ever going to run against mysql, you may enable query "
      99                 :                                 "buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.",
     100                 :                                 dbh->is_persistent);
     101             593 :                 } else if (einfo->errcode == 2057) {
     102               0 :                         einfo->errmsg = pestrdup(
     103                 :                                 "A stored procedure returning result sets of different size was called. "
     104                 :                                 "This is not supported by libmysql",
     105                 :                                 dbh->is_persistent);
     106                 : 
     107                 :                 } else {
     108             593 :                         einfo->errmsg = pestrdup(mysql_error(H->server), dbh->is_persistent);
     109                 :                 }
     110                 :         } else { /* no error */
     111              10 :                 strcpy(*pdo_err, PDO_ERR_NONE);
     112              10 :                 PDO_DBG_RETURN(0);
     113                 :         }
     114                 : 
     115                 : #if HAVE_MYSQL_SQLSTATE || PDO_USE_MYSQLND
     116                 : # if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
     117             628 :         if (S && S->stmt) {
     118               3 :                 strcpy(*pdo_err, mysql_stmt_sqlstate(S->stmt));
     119                 :         } else
     120                 : # endif
     121                 :         {
     122             598 :                 strcpy(*pdo_err, mysql_sqlstate(H->server));
     123                 :         }
     124                 : #else
     125                 :         strcpy(*pdo_err, pdo_mysql_get_sqlstate(einfo->errcode));
     126                 : #endif
     127                 : 
     128             601 :         if (!dbh->methods) {
     129              10 :                 PDO_DBG_INF("Throwing exception");
     130              10 :                 zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
     131                 :                                 *pdo_err, einfo->errcode, einfo->errmsg);
     132                 :         }
     133                 : 
     134             601 :         PDO_DBG_RETURN(einfo->errcode);
     135                 : }
     136                 : /* }}} */
     137                 : 
     138                 : /* {{{ pdo_mysql_fetch_error_func */
     139                 : static int pdo_mysql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
     140             848 : {
     141             848 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     142             848 :         pdo_mysql_error_info *einfo = &H->einfo;
     143                 : 
     144             848 :         PDO_DBG_ENTER("pdo_mysql_fetch_error_func");
     145             848 :         PDO_DBG_INF_FMT("dbh=%p stmt=%p", dbh, stmt);
     146             848 :         if (stmt) {
     147             781 :                 pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
     148             781 :                 einfo = &S->einfo;
     149                 :         } else {
     150              67 :                 einfo = &H->einfo;
     151                 :         }
     152                 : 
     153             848 :         if (einfo->errcode) {
     154              81 :                 add_next_index_long(info, einfo->errcode);
     155              81 :                 add_next_index_string(info, einfo->errmsg, 1);
     156                 :         }
     157                 : 
     158             848 :         PDO_DBG_RETURN(1);
     159                 : }
     160                 : /* }}} */
     161                 : 
     162                 : /* {{{ mysql_handle_closer */
     163                 : static int mysql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
     164             425 : {
     165             425 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     166                 :         
     167             425 :         PDO_DBG_ENTER("mysql_handle_closer");
     168             425 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     169             425 :         if (H) {
     170             425 :                 if (H->server) {
     171             425 :                         mysql_close(H->server);
     172             425 :                         H->server = NULL;
     173                 :                 }
     174             425 :                 if (H->einfo.errmsg) {
     175             221 :                         pefree(H->einfo.errmsg, dbh->is_persistent);
     176             221 :                         H->einfo.errmsg = NULL;
     177                 :                 }
     178             425 :                 pefree(H, dbh->is_persistent);
     179             425 :                 dbh->driver_data = NULL;
     180                 :         }
     181             425 :         PDO_DBG_RETURN(0);
     182                 : }
     183                 : /* }}} */
     184                 : 
     185                 : /* {{{ mysql_handle_preparer */
     186                 : static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
     187            1558 : {
     188            1558 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     189            1558 :         pdo_mysql_stmt *S = ecalloc(1, sizeof(pdo_mysql_stmt));
     190                 : #if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
     191            1558 :         char *nsql = NULL;
     192            1558 :         int nsql_len = 0;
     193                 :         int ret;
     194                 :         int server_version;
     195                 : #endif
     196                 :         
     197            1558 :         PDO_DBG_ENTER("mysql_handle_preparer");
     198            1558 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     199            1558 :         PDO_DBG_INF_FMT("sql=%.*s", sql_len, sql);
     200                 : 
     201            1558 :         S->H = H;
     202            1558 :         stmt->driver_data = S;
     203            1558 :         stmt->methods = &mysql_stmt_methods;
     204                 : 
     205            1558 :         if (H->emulate_prepare) {
     206             769 :                 goto end;
     207                 :         }
     208                 : 
     209                 : #if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
     210             789 :         server_version = mysql_get_server_version(H->server);
     211             789 :         if (server_version < 40100) {
     212               0 :                 goto fallback;
     213                 :         }
     214             789 :         stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
     215             789 :         ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len TSRMLS_CC);
     216                 : 
     217             789 :         if (ret == 1) {
     218                 :                 /* query was rewritten */
     219             113 :                 sql = nsql;
     220             113 :                 sql_len = nsql_len;
     221             676 :         } else if (ret == -1) {
     222                 :                 /* failed to parse */
     223               1 :                 strcpy(dbh->error_code, stmt->error_code);
     224               1 :                 PDO_DBG_RETURN(0);
     225                 :         }
     226                 : 
     227             788 :         if (!(S->stmt = mysql_stmt_init(H->server))) {
     228               0 :                 pdo_mysql_error(dbh);
     229               0 :                 if (nsql) {
     230               0 :                         efree(nsql);
     231                 :                 }
     232               0 :                 PDO_DBG_RETURN(0);
     233                 :         }
     234                 :         
     235             788 :         if (mysql_stmt_prepare(S->stmt, sql, sql_len)) {
     236                 :                 /* TODO: might need to pull statement specific info here? */
     237                 :                 /* if the query isn't supported by the protocol, fallback to emulation */
     238              11 :                 if (mysql_errno(H->server) == 1295) {
     239               1 :                         if (nsql) {
     240               0 :                                 efree(nsql);
     241                 :                         }
     242               1 :                         goto fallback;
     243                 :                 }
     244              10 :                 pdo_mysql_error(dbh);
     245              10 :                 if (nsql) {
     246               1 :                         efree(nsql);
     247                 :                 }
     248              10 :                 PDO_DBG_RETURN(0);
     249                 :         }
     250             777 :         if (nsql) {
     251             112 :                 efree(nsql);
     252                 :         }
     253                 : 
     254             777 :         S->num_params = mysql_stmt_param_count(S->stmt);
     255                 : 
     256             777 :         if (S->num_params) {
     257             378 :                 S->params_given = 0;
     258                 : #if PDO_USE_MYSQLND
     259             378 :                 S->params = NULL;
     260                 : #else
     261                 :                 S->params = ecalloc(S->num_params, sizeof(MYSQL_BIND));
     262                 :                 S->in_null = ecalloc(S->num_params, sizeof(my_bool));
     263                 :                 S->in_length = ecalloc(S->num_params, sizeof(unsigned long));
     264                 : #endif
     265                 :         }
     266             777 :         dbh->alloc_own_columns = 1;
     267                 : 
     268             777 :         S->max_length = pdo_attr_lval(driver_options, PDO_ATTR_MAX_COLUMN_LEN, 0 TSRMLS_CC);
     269                 : 
     270             777 :         PDO_DBG_RETURN(1);
     271                 : 
     272             770 : fallback:
     273                 : #endif
     274             770 : end:
     275             770 :         stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
     276                 :         
     277             770 :         PDO_DBG_RETURN(1);
     278                 : }
     279                 : /* }}} */
     280                 : 
     281                 : /* {{{ mysql_handle_doer */
     282                 : static long mysql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
     283            1557 : {
     284            1557 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     285            1557 :         PDO_DBG_ENTER("mysql_handle_doer");
     286            1557 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     287            1557 :         PDO_DBG_INF_FMT("sql=%.*s", sql_len, sql);
     288                 : 
     289            1557 :         if (mysql_real_query(H->server, sql, sql_len)) {
     290             557 :                 pdo_mysql_error(dbh);
     291             557 :                 PDO_DBG_RETURN(-1);
     292                 :         } else {
     293            1000 :                 my_ulonglong c = mysql_affected_rows(H->server);
     294            1000 :                 if (c == (my_ulonglong) -1) {
     295               3 :                         pdo_mysql_error(dbh);
     296               3 :                         PDO_DBG_RETURN(H->einfo.errcode ? -1 : 0);
     297                 :                 } else {
     298                 : 
     299                 : #if HAVE_MYSQL_NEXT_RESULT || PDO_USE_MYSQLND
     300                 :                         /* MULTI_QUERY support - eat up all unfetched result sets */
     301                 :                         MYSQL_RES* result;
     302            1998 :                         while (mysql_more_results(H->server)) {
     303               4 :                                 if (mysql_next_result(H->server)) {
     304               0 :                                         PDO_DBG_RETURN(1);
     305                 :                                 }
     306               4 :                                 result = mysql_store_result(H->server);
     307               4 :                                 if (result) {
     308               0 :                                         mysql_free_result(result);
     309                 :                                 }
     310                 :                         }
     311                 : #endif
     312             997 :                         PDO_DBG_RETURN((int)c);
     313                 :                 }
     314                 :         }
     315                 : }
     316                 : /* }}} */
     317                 : 
     318                 : /* {{{ pdo_mysql_last_insert_id */
     319                 : static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
     320              12 : {
     321              12 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     322              12 :         char *id = php_pdo_int64_to_str(mysql_insert_id(H->server) TSRMLS_CC);
     323              12 :         PDO_DBG_ENTER("pdo_mysql_last_insert_id");
     324              12 :         *len = strlen(id);
     325              12 :         PDO_DBG_RETURN(id);
     326                 : }
     327                 : 
     328                 : /* {{{ mysql_handle_quoter */
     329                 : static int mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype  TSRMLS_DC)
     330             247 : {
     331             247 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     332             247 :         PDO_DBG_ENTER("mysql_handle_quoter");
     333             247 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     334             247 :         PDO_DBG_INF_FMT("unquoted=%.*s", unquotedlen, unquoted);
     335             247 :         *quoted = safe_emalloc(2, unquotedlen, 3);
     336             247 :         *quotedlen = mysql_real_escape_string(H->server, *quoted + 1, unquoted, unquotedlen);
     337             247 :         (*quoted)[0] =(*quoted)[++*quotedlen] = '\'';
     338             247 :         (*quoted)[++*quotedlen] = '\0';
     339             247 :         PDO_DBG_INF_FMT("quoted=%.*s", *quotedlen, *quoted);
     340             247 :         PDO_DBG_RETURN(1);
     341                 : }
     342                 : /* }}} */
     343                 : 
     344                 : /* {{{ mysql_handle_begin */
     345                 : static int mysql_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
     346              21 : {
     347              21 :         PDO_DBG_ENTER("mysql_handle_quoter");
     348              21 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     349              21 :         PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("START TRANSACTION") TSRMLS_CC));
     350                 : }
     351                 : /* }}} */
     352                 : 
     353                 : /* {{{ mysql_handle_commit */
     354                 : static int mysql_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
     355              10 : {
     356              10 :         PDO_DBG_ENTER("mysql_handle_commit");
     357              10 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     358                 : #if MYSQL_VERSION_ID >= 40100 || defined(PDO_USE_MYSQLND)
     359              10 :         PDO_DBG_RETURN(0 <= mysql_commit(((pdo_mysql_db_handle *)dbh->driver_data)->server));
     360                 : #else
     361                 :         PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("COMMIT") TSRMLS_CC));
     362                 : #endif
     363                 : }
     364                 : 
     365                 : /* {{{ mysql_handle_rollback */
     366                 : static int mysql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
     367              11 : {
     368              11 :         PDO_DBG_ENTER("mysql_handle_rollback");
     369              11 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     370                 : #if MYSQL_VERSION_ID >= 40100 || defined(PDO_USE_MYSQLND)
     371              11 :         PDO_DBG_RETURN(0 <= mysql_rollback(((pdo_mysql_db_handle *)dbh->driver_data)->server));
     372                 : #else
     373                 :         PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("ROLLBACK") TSRMLS_CC));
     374                 : #endif
     375                 : }
     376                 : /* }}} */
     377                 : 
     378                 : /* {{{ mysql_handle_autocommit */
     379                 : static inline int mysql_handle_autocommit(pdo_dbh_t *dbh TSRMLS_DC)
     380               7 : {
     381               7 :         PDO_DBG_ENTER("mysql_handle_autocommit");
     382               7 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     383               7 :         PDO_DBG_INF_FMT("dbh->autocommit=%d", dbh->auto_commit);
     384                 : #if MYSQL_VERSION_ID >= 40100 || defined(PDO_USE_MYSQLND)
     385               7 :         PDO_DBG_RETURN(0 <= mysql_autocommit(((pdo_mysql_db_handle *)dbh->driver_data)->server, dbh->auto_commit));
     386                 : #else
     387                 :         if (dbh->auto_commit) {
     388                 :                 PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("SET AUTOCOMMIT=1") TSRMLS_CC));
     389                 :         } else {
     390                 :                 PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("SET AUTOCOMMIT=0") TSRMLS_CC));
     391                 :         }
     392                 : #endif
     393                 : }
     394                 : /* }}} */
     395                 : 
     396                 : /* {{{ pdo_mysql_set_attribute */
     397                 : static int pdo_mysql_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
     398             294 : {
     399             294 :         PDO_DBG_ENTER("pdo_mysql_set_attribute");
     400             294 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     401             294 :         PDO_DBG_INF_FMT("attr=%l", attr);
     402             294 :         switch (attr) {
     403                 :                 case PDO_ATTR_AUTOCOMMIT:               
     404              10 :                         convert_to_boolean(val);
     405                 :         
     406                 :                         /* ignore if the new value equals the old one */                        
     407              10 :                         if (dbh->auto_commit ^ Z_BVAL_P(val)) {
     408               6 :                                 dbh->auto_commit = Z_BVAL_P(val);
     409               6 :                                 mysql_handle_autocommit(dbh TSRMLS_CC);
     410                 :                         }
     411              10 :                         PDO_DBG_RETURN(1);
     412                 : 
     413                 :                 case PDO_MYSQL_ATTR_USE_BUFFERED_QUERY:
     414              32 :                         ((pdo_mysql_db_handle *)dbh->driver_data)->buffered = Z_BVAL_P(val);
     415              32 :                         PDO_DBG_RETURN(1);
     416                 :                 case PDO_MYSQL_ATTR_DIRECT_QUERY:
     417                 :                 case PDO_ATTR_EMULATE_PREPARES:
     418             209 :                         ((pdo_mysql_db_handle *)dbh->driver_data)->emulate_prepare = Z_BVAL_P(val);
     419             209 :                         PDO_DBG_RETURN(1);
     420                 :                 case PDO_ATTR_FETCH_TABLE_NAMES:
     421               2 :                         ((pdo_mysql_db_handle *)dbh->driver_data)->fetch_table_names = Z_BVAL_P(val);
     422               2 :                         PDO_DBG_RETURN(1);
     423                 : #ifndef PDO_USE_MYSQLND
     424                 :                 case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE:
     425                 :                         if (Z_LVAL_P(val) < 0) {
     426                 :                                 /* TODO: Johannes, can we throw a warning here? */
     427                 :                                 ((pdo_mysql_db_handle *)dbh->driver_data)->max_buffer_size = 1024*1024;
     428                 :                                 PDO_DBG_INF_FMT("Adjusting invalid buffer size to =%l", ((pdo_mysql_db_handle *)dbh->driver_data)->max_buffer_size);
     429                 :                         } else {
     430                 :                                 ((pdo_mysql_db_handle *)dbh->driver_data)->max_buffer_size = Z_LVAL_P(val);
     431                 :                         }
     432                 :                         PDO_DBG_RETURN(1);
     433                 :                         break;
     434                 : #endif
     435                 : 
     436                 :                 default:
     437              41 :                         PDO_DBG_RETURN(0);
     438                 :         }
     439                 : }
     440                 : /* }}} */
     441                 : 
     442                 : /* {{{ pdo_mysql_get_attribute */
     443                 : static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
     444              88 : {
     445              88 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     446                 : 
     447              88 :         PDO_DBG_ENTER("pdo_mysql_get_attribute");
     448              88 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     449              88 :         PDO_DBG_INF_FMT("attr=%l", attr);
     450              88 :         switch (attr) {
     451                 :                 case PDO_ATTR_CLIENT_VERSION:
     452               3 :                         ZVAL_STRING(return_value, (char *)mysql_get_client_info(), 1);
     453               3 :                         break;
     454                 : 
     455                 :                 case PDO_ATTR_SERVER_VERSION:
     456               3 :                         ZVAL_STRING(return_value, (char *)mysql_get_server_info(H->server), 1);
     457               3 :                         break;
     458                 : 
     459                 :                 case PDO_ATTR_CONNECTION_STATUS:
     460               2 :                         ZVAL_STRING(return_value, (char *)mysql_get_host_info(H->server), 1);
     461               2 :                         break;
     462                 :                 case PDO_ATTR_SERVER_INFO: {
     463                 :                         char *tmp;
     464                 : #if PDO_USE_MYSQLND
     465                 :                         int tmp_len;
     466                 : 
     467               2 :                         if (mysqlnd_stat(H->server, &tmp, &tmp_len) == PASS) {
     468               2 :                                 ZVAL_STRINGL(return_value, tmp, tmp_len, 0);
     469                 : #else
     470                 :                         if ((tmp = (char *)mysql_stat(H->server))) {
     471                 :                                 ZVAL_STRING(return_value, tmp, 1);
     472                 : #endif
     473                 :                         } else {
     474               0 :                                 pdo_mysql_error(dbh);
     475               0 :                                 PDO_DBG_RETURN(-1);
     476                 :                         }
     477                 :                 }
     478               2 :                         break;
     479                 :                 case PDO_ATTR_AUTOCOMMIT:
     480              17 :                         ZVAL_LONG(return_value, dbh->auto_commit);
     481              17 :                         break;
     482                 :                         
     483                 :                 case PDO_MYSQL_ATTR_USE_BUFFERED_QUERY:
     484               3 :                         ZVAL_LONG(return_value, H->buffered);
     485               3 :                         break;
     486                 : 
     487                 :                 case PDO_MYSQL_ATTR_DIRECT_QUERY:
     488              43 :                         ZVAL_LONG(return_value, H->emulate_prepare);
     489              43 :                         break;
     490                 : 
     491                 : #ifndef PDO_USE_MYSQLND
     492                 :                 case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE:
     493                 :                         ZVAL_LONG(return_value, H->max_buffer_size);
     494                 :                         break;
     495                 : #endif
     496                 : 
     497                 :                 default:
     498              15 :                         PDO_DBG_RETURN(0);      
     499                 :         }
     500                 : 
     501              73 :         PDO_DBG_RETURN(1);
     502                 : }
     503                 : /* }}} */
     504                 : 
     505                 : /* {{{ pdo_mysql_check_liveness */
     506                 : static int pdo_mysql_check_liveness(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
     507              24 : {
     508              24 :         pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
     509                 : #if MYSQL_VERSION_ID <= 32230
     510                 :         void (*handler) (int);
     511                 :         unsigned int my_errno;
     512                 : #endif
     513                 : 
     514              24 :         PDO_DBG_ENTER("pdo_mysql_check_liveness");
     515              24 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     516                 : 
     517                 : #if MYSQL_VERSION_ID > 32230
     518              24 :         if (mysql_ping(H->server)) {
     519               0 :                 PDO_DBG_RETURN(FAILURE);
     520                 :         }
     521                 : #else /* no mysql_ping() */
     522                 :         handler = signal(SIGPIPE, SIG_IGN);
     523                 :         mysql_stat(H->server);
     524                 :         switch (mysql_errno(H->server)) {
     525                 :                 case CR_SERVER_GONE_ERROR:
     526                 :                 case CR_SERVER_LOST:
     527                 :                         signal(SIGPIPE, handler);
     528                 :                         PDO_DBG_RETURN(FAILURE);
     529                 :                 default:
     530                 :                         break;
     531                 :         }
     532                 :         signal(SIGPIPE, handler);
     533                 : #endif /* end mysql_ping() */
     534              24 :         PDO_DBG_RETURN(SUCCESS);
     535                 : } 
     536                 : /* }}} */
     537                 : 
     538                 : /* {{{ mysql_methods */
     539                 : static struct pdo_dbh_methods mysql_methods = {
     540                 :         mysql_handle_closer,
     541                 :         mysql_handle_preparer,
     542                 :         mysql_handle_doer,
     543                 :         mysql_handle_quoter,
     544                 :         mysql_handle_begin,
     545                 :         mysql_handle_commit,
     546                 :         mysql_handle_rollback,
     547                 :         pdo_mysql_set_attribute,
     548                 :         pdo_mysql_last_insert_id,
     549                 :         pdo_mysql_fetch_error_func,
     550                 :         pdo_mysql_get_attribute,
     551                 :         pdo_mysql_check_liveness
     552                 : };
     553                 : /* }}} */
     554                 : 
     555                 : #ifdef PDO_USE_MYSQLND
     556                 : # ifdef PHP_WIN32
     557                 : #  define MYSQL_UNIX_ADDR       "MySQL"
     558                 : # else
     559                 : #  define MYSQL_UNIX_ADDR       PDO_MYSQL_G(default_socket)
     560                 : # endif
     561                 : #endif
     562                 : 
     563                 : /* {{{ pdo_mysql_handle_factory */
     564                 : static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
     565             426 : {
     566                 :         pdo_mysql_db_handle *H;
     567             426 :         int i, ret = 0;
     568             426 :         char *host = NULL, *unix_socket = NULL;
     569             426 :         unsigned int port = 3306;
     570                 :         char *dbname;
     571                 :         struct pdo_data_src_parser vars[] = {
     572                 :                 { "charset",  NULL,   0 },
     573                 :                 { "dbname",   "",   0 },
     574                 :                 { "host",   "localhost",    0 },
     575                 :                 { "port",   "3306", 0 },
     576                 :                 { "unix_socket",  MYSQL_UNIX_ADDR,    0 },
     577             426 :         };
     578                 :         int connect_opts = 0
     579                 : #ifdef CLIENT_MULTI_RESULTS
     580                 :                 |CLIENT_MULTI_RESULTS
     581                 : #endif
     582                 : #ifdef CLIENT_MULTI_STATEMENTS
     583                 :                 |CLIENT_MULTI_STATEMENTS
     584                 : #endif
     585             426 :                 ;
     586                 : 
     587                 : #if PDO_USE_MYSQLND
     588             426 :         int dbname_len = 0;
     589             426 :         int password_len = 0;
     590                 : #endif
     591             426 :         PDO_DBG_ENTER("pdo_mysql_handle_factory");
     592             426 :         PDO_DBG_INF_FMT("dbh=%p", dbh);
     593                 : #ifdef CLIENT_MULTI_RESULTS
     594             426 :         PDO_DBG_INF("multi results");
     595                 : #endif
     596                 : 
     597             426 :         php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
     598                 : 
     599             426 :         H = pecalloc(1, sizeof(pdo_mysql_db_handle), dbh->is_persistent);
     600                 : 
     601             426 :         H->einfo.errcode = 0;
     602             426 :         H->einfo.errmsg = NULL;
     603                 : 
     604                 :         /* allocate an environment */
     605                 : 
     606                 :         /* handle for the server */
     607             426 :         if (!(H->server = pdo_mysql_init(dbh->is_persistent))) {
     608               0 :                 pdo_mysql_error(dbh);
     609               0 :                 goto cleanup;
     610                 :         }
     611                 :         
     612             426 :         dbh->driver_data = H;
     613                 : 
     614                 : #ifndef PDO_USE_MYSQLND
     615                 :         H->max_buffer_size = 1024*1024;
     616                 : #endif
     617                 : 
     618             426 :         H->buffered = H->emulate_prepare = 1;
     619                 : 
     620                 :         /* handle MySQL options */
     621             426 :         if (driver_options) {
     622              24 :                 long connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
     623              24 :                 long local_infile = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_LOCAL_INFILE, 0 TSRMLS_CC);
     624              24 :                 char *init_cmd = NULL;
     625                 : #ifndef PDO_USE_MYSQLND
     626                 :                 char *default_file = NULL, *default_group = NULL;
     627                 :                 long compress = 0;
     628                 : #endif
     629              24 :                 H->buffered = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY, 1 TSRMLS_CC);
     630                 : 
     631              24 :                 H->emulate_prepare = pdo_attr_lval(driver_options,
     632                 :                         PDO_MYSQL_ATTR_DIRECT_QUERY, H->emulate_prepare TSRMLS_CC);
     633              24 :                 H->emulate_prepare = pdo_attr_lval(driver_options, 
     634                 :                         PDO_ATTR_EMULATE_PREPARES, H->emulate_prepare TSRMLS_CC);
     635                 : 
     636                 : #ifndef PDO_USE_MYSQLND
     637                 :                 H->max_buffer_size = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_MAX_BUFFER_SIZE, H->max_buffer_size TSRMLS_CC);
     638                 : #endif
     639                 : 
     640              24 :                 if (pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_FOUND_ROWS, 0 TSRMLS_CC)) {
     641               0 :                         connect_opts |= CLIENT_FOUND_ROWS;
     642                 :                 }
     643                 : 
     644              24 :                 if (pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_IGNORE_SPACE, 0 TSRMLS_CC)) {
     645               0 :                         connect_opts |= CLIENT_IGNORE_SPACE;
     646                 :                 }
     647                 : 
     648              24 :                 if (mysql_options(H->server, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout)) {
     649               0 :                         pdo_mysql_error(dbh);
     650               0 :                         goto cleanup;
     651                 :                 }
     652                 : 
     653                 : #if PHP_MAJOR_VERSION < 6
     654                 :                 if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode))
     655                 : #else
     656              24 :                 if (PG(open_basedir) && PG(open_basedir)[0] != '\0') 
     657                 : #endif
     658                 :                 {
     659               0 :                         local_infile = 0;
     660                 :                 }
     661                 : #ifdef MYSQL_OPT_LOCAL_INFILE
     662                 :                 if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) {
     663                 :                         pdo_mysql_error(dbh);
     664                 :                         goto cleanup;
     665                 :                 }
     666                 : #endif
     667                 : #ifdef MYSQL_OPT_RECONNECT
     668                 :                 /* since 5.0.3, the default for this option is 0 if not specified.
     669                 :                  * we want the old behaviour */
     670                 :                 {
     671                 :                         long reconnect = 1;
     672                 :                         mysql_options(H->server, MYSQL_OPT_RECONNECT, (const char*)&reconnect);
     673                 :                 }
     674                 : #endif
     675              24 :                 init_cmd = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_INIT_COMMAND, NULL TSRMLS_CC);
     676              24 :                 if (init_cmd) {
     677               4 :                         if (mysql_options(H->server, MYSQL_INIT_COMMAND, (const char *)init_cmd)) {
     678               0 :                                 efree(init_cmd);
     679               0 :                                 pdo_mysql_error(dbh);
     680               0 :                                 goto cleanup;
     681                 :                         }
     682               4 :                         efree(init_cmd);
     683                 :                 }
     684                 : #ifndef PDO_USE_MYSQLND         
     685                 :                 default_file = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_READ_DEFAULT_FILE, NULL TSRMLS_CC);
     686                 :                 if (default_file) {
     687                 :                         if (mysql_options(H->server, MYSQL_READ_DEFAULT_FILE, (const char *)default_file)) {
     688                 :                                 efree(default_file);
     689                 :                                 pdo_mysql_error(dbh);
     690                 :                                 goto cleanup;
     691                 :                         }
     692                 :                         efree(default_file);
     693                 :                 }
     694                 :                 
     695                 :                 default_group= pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_READ_DEFAULT_GROUP, NULL TSRMLS_CC);
     696                 :                 if (default_group) {
     697                 :                         if (mysql_options(H->server, MYSQL_READ_DEFAULT_GROUP, (const char *)default_group)) {
     698                 :                                 efree(default_group);
     699                 :                                 pdo_mysql_error(dbh);
     700                 :                                 goto cleanup;
     701                 :                         }
     702                 :                         efree(default_group);
     703                 :                 }
     704                 : 
     705                 :                 compress = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_COMPRESS, 0 TSRMLS_CC);
     706                 :                 if (compress) {
     707                 :                         if (mysql_options(H->server, MYSQL_OPT_COMPRESS, 0)) {
     708                 :                                 pdo_mysql_error(dbh);
     709                 :                                 goto cleanup;
     710                 :                         }
     711                 :                 }
     712                 : #endif
     713                 :         }
     714                 : 
     715             426 :         dbname = vars[1].optval;
     716             426 :         host = vars[2].optval;  
     717             426 :         if(vars[3].optval) {
     718             426 :                 port = atoi(vars[3].optval);
     719                 :         }
     720             426 :         if (vars[2].optval && !strcmp("localhost", vars[2].optval)) {
     721             422 :                 unix_socket = vars[4].optval;  
     722                 :         }
     723                 : 
     724                 :         /* TODO: - Check zval cache + ZTS */
     725                 : #ifdef PDO_USE_MYSQLND
     726             426 :         if (dbname) {
     727             426 :                 dbname_len = strlen(dbname);
     728                 :         }
     729                 : 
     730             426 :         if (dbh->password) {
     731             425 :                 password_len = strlen(dbh->password);
     732                 :         }
     733                 : 
     734             426 :         if (mysqlnd_connect(H->server, host, dbh->username, dbh->password, password_len, dbname, dbname_len,
     735                 :                                                 port, unix_socket, connect_opts, PDO_MYSQL_G(mysqlnd_thd_zval_cache) TSRMLS_CC) == NULL) {
     736                 : #else
     737                 :         if (mysql_real_connect(H->server, host, dbh->username, dbh->password, dbname, port, unix_socket, connect_opts) == NULL) {
     738                 : #endif
     739              10 :                 pdo_mysql_error(dbh);
     740              10 :                 goto cleanup;
     741                 :         }
     742                 : 
     743             416 :         if (!dbh->auto_commit) {
     744               1 :                 mysql_handle_autocommit(dbh TSRMLS_CC);
     745                 :         }
     746                 : 
     747             416 :         H->attached = 1;
     748                 : 
     749             416 :         dbh->alloc_own_columns = 1;
     750             416 :         dbh->max_escaped_char_length = 2;
     751             416 :         dbh->methods = &mysql_methods;
     752                 : 
     753             416 :         ret = 1;
     754                 :         
     755             426 : cleanup:
     756            2556 :         for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
     757            2130 :                 if (vars[i].freeme) {
     758             842 :                         efree(vars[i].optval);
     759                 :                 }
     760                 :         }
     761                 :         
     762             426 :         dbh->methods = &mysql_methods;
     763                 : 
     764             426 :         PDO_DBG_RETURN(ret);
     765                 : }
     766                 : /* }}} */
     767                 : 
     768                 : pdo_driver_t pdo_mysql_driver = {
     769                 :         PDO_DRIVER_HEADER(mysql),
     770                 :         pdo_mysql_handle_factory
     771                 : };
     772                 : 
     773                 : /*
     774                 :  * Local variables:
     775                 :  * tab-width: 4
     776                 :  * c-basic-offset: 4
     777                 :  * End:
     778                 :  * vim600: noet sw=4 ts=4 fdm=marker
     779                 :  * vim<600: noet sw=4 ts=4
     780                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:34 +0000 (33 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.