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

LCOV - code coverage report
Current view: top level - ext/pdo_mysql - mysql_driver.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 283 327 86.5 %
Date: 2014-12-13 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:18 +0000 (7 days ago)

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