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: 274 313 87.5 %
Date: 2014-07-23 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 23 Jul 2014 19:58:36 +0000 (19 hours ago)

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