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 - pdo.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 113 160 70.6 %
Date: 2014-07-21 Functions: 13 15 86.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       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: Wez Furlong <wez@php.net>                                    |
      16             :   |         Marcus Boerger <helly@php.net>                               |
      17             :   |         Sterling Hughes <sterling@php.net>                           |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include <ctype.h>
      28             : #include "php.h"
      29             : #include "php_ini.h"
      30             : #include "ext/standard/info.h"
      31             : #include "php_pdo.h"
      32             : #include "php_pdo_driver.h"
      33             : #include "php_pdo_int.h"
      34             : #include "zend_exceptions.h"
      35             : 
      36             : static zend_class_entry *spl_ce_RuntimeException;
      37             : 
      38             : ZEND_DECLARE_MODULE_GLOBALS(pdo)
      39             : static PHP_GINIT_FUNCTION(pdo);
      40             : 
      41             : /* True global resources - no need for thread safety here */
      42             : 
      43             : /* the registry of PDO drivers */
      44             : HashTable pdo_driver_hash;
      45             : 
      46             : /* we use persistent resources for the driver connection stuff */
      47             : static int le_ppdo;
      48             : 
      49          41 : int php_pdo_list_entry(void)
      50             : {
      51          41 :         return le_ppdo;
      52             : }
      53             : 
      54             : /* for exceptional circumstances */
      55             : zend_class_entry *pdo_exception_ce;
      56             : 
      57     2083186 : PDO_API zend_class_entry *php_pdo_get_dbh_ce(void)
      58             : {
      59     2083186 :         return pdo_dbh_ce;
      60             : }
      61             : 
      62          75 : PDO_API zend_class_entry *php_pdo_get_exception(void)
      63             : {
      64          75 :         return pdo_exception_ce;
      65             : }
      66             : 
      67           0 : PDO_API char *php_pdo_str_tolower_dup(const char *src, int len)
      68             : {
      69           0 :         char *dest = emalloc(len + 1);
      70           0 :         zend_str_tolower_copy(dest, src, len);
      71           0 :         return dest;
      72             : }
      73             : 
      74       21294 : PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC)
      75             : {
      76             : #if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
      77       21294 :         if (!root) {
      78       21257 :                 if (!spl_ce_RuntimeException) {
      79             :                         zend_class_entry **pce;
      80             : 
      81       21257 :                         if (zend_hash_find(CG(class_table), "runtimeexception", sizeof("RuntimeException"), (void **) &pce) == SUCCESS) {
      82       21257 :                                 spl_ce_RuntimeException = *pce;
      83       21257 :                                 return *pce;
      84             :                         }
      85             :                 } else {
      86           0 :                         return spl_ce_RuntimeException;
      87             :                 }
      88             :         }
      89             : #endif
      90             : #if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2)
      91             :         return zend_exception_get_default();
      92             : #else
      93          37 :         return zend_exception_get_default(TSRMLS_C);
      94             : #endif
      95             : }
      96             : 
      97             : zend_class_entry *pdo_dbh_ce, *pdo_dbstmt_ce, *pdo_row_ce;
      98             : 
      99             : /* {{{ proto array pdo_drivers()
     100             :  Return array of available PDO drivers */
     101           0 : PHP_FUNCTION(pdo_drivers)
     102             : {
     103             :         HashPosition pos;
     104             :         pdo_driver_t **pdriver;
     105             : 
     106           0 :         if (zend_parse_parameters_none() == FAILURE) {
     107           0 :                 return;
     108             :         }
     109             :         
     110           0 :         array_init(return_value);
     111             : 
     112           0 :         zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
     113           0 :         while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
     114           0 :                 add_next_index_stringl(return_value, (char*)(*pdriver)->driver_name, (*pdriver)->driver_name_len, 1);
     115           0 :                 zend_hash_move_forward_ex(&pdo_driver_hash, &pos);
     116             :         }
     117             : }
     118             : /* }}} */
     119             : 
     120             : /* {{{ arginfo */
     121             : ZEND_BEGIN_ARG_INFO(arginfo_pdo_drivers, 0)
     122             : ZEND_END_ARG_INFO()
     123             : /* }}} */
     124             : 
     125             : /* {{{ pdo_functions[] */
     126             : const zend_function_entry pdo_functions[] = {
     127             :         PHP_FE(pdo_drivers,             arginfo_pdo_drivers)
     128             :         PHP_FE_END
     129             : };
     130             : /* }}} */
     131             : 
     132             : /* {{{ pdo_functions[] */
     133             : #if ZEND_MODULE_API_NO >= 20050922
     134             : static const zend_module_dep pdo_deps[] = {
     135             : #ifdef HAVE_SPL
     136             :         ZEND_MOD_REQUIRED("spl")
     137             : #endif
     138             :         ZEND_MOD_END
     139             : };
     140             : #endif
     141             : /* }}} */
     142             : 
     143             : /* {{{ pdo_module_entry */
     144             : zend_module_entry pdo_module_entry = {
     145             : #if ZEND_MODULE_API_NO >= 20050922
     146             :         STANDARD_MODULE_HEADER_EX, NULL,
     147             :         pdo_deps,
     148             : #else
     149             :         STANDARD_MODULE_HEADER,
     150             : #endif
     151             :         "PDO",
     152             :         pdo_functions,
     153             :         PHP_MINIT(pdo),
     154             :         PHP_MSHUTDOWN(pdo),
     155             :         NULL,
     156             :         NULL,
     157             :         PHP_MINFO(pdo),
     158             :         "1.0.4dev",
     159             :         PHP_MODULE_GLOBALS(pdo),
     160             :         PHP_GINIT(pdo),
     161             :         NULL,
     162             :         NULL,
     163             :         STANDARD_MODULE_PROPERTIES_EX
     164             : };
     165             : /* }}} */
     166             : 
     167             : /* TODO: visit persistent handles: for each persistent statement handle,
     168             :  * remove bound parameter associations */
     169             : 
     170             : #ifdef COMPILE_DL_PDO
     171             : ZEND_GET_MODULE(pdo)
     172             : #endif
     173             : 
     174             : /* {{{ PHP_GINIT_FUNCTION */
     175       21257 : static PHP_GINIT_FUNCTION(pdo)
     176             : {
     177       21257 :         pdo_globals->global_value = 0;
     178       21257 : }
     179             : /* }}} */
     180             : 
     181      148799 : PDO_API int php_pdo_register_driver(pdo_driver_t *driver)
     182             : {
     183      148799 :         if (driver->api_version != PDO_DRIVER_API) {
     184           0 :                 zend_error(E_ERROR, "PDO: driver %s requires PDO API version %ld; this is PDO version %d",
     185           0 :                         driver->driver_name, driver->api_version, PDO_DRIVER_API);
     186           0 :                 return FAILURE;
     187             :         }
     188      148799 :         if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
     189           0 :                 zend_error(E_ERROR, "You MUST load PDO before loading any PDO drivers");
     190           0 :                 return FAILURE; /* NOTREACHED */
     191             :         }
     192             : 
     193      148799 :         return zend_hash_add(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len,
     194             :                         (void**)&driver, sizeof(pdo_driver_t *), NULL);
     195             : }
     196             : 
     197      149030 : PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver)
     198             : {
     199      149030 :         if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
     200           0 :                 return;
     201             :         }
     202             : 
     203      149030 :         zend_hash_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
     204             : }
     205             : 
     206        1225 : pdo_driver_t *pdo_find_driver(const char *name, int namelen)
     207             : {
     208        1225 :         pdo_driver_t **driver = NULL;
     209             :         
     210        1225 :         zend_hash_find(&pdo_driver_hash, (char*)name, namelen, (void**)&driver);
     211             : 
     212        1225 :         return driver ? *driver : NULL;
     213             : }
     214             : 
     215         762 : PDO_API int php_pdo_parse_data_source(const char *data_source,
     216             :                 unsigned long data_source_len, struct pdo_data_src_parser *parsed,
     217             :                 int nparams)
     218             : {
     219             :         int i, j;
     220         762 :         int valstart = -1;
     221         762 :         int semi = -1;
     222         762 :         int optstart = 0;
     223             :         int nlen;
     224         762 :         int n_matches = 0;
     225         762 :         int n_semicolumns = 0;
     226             : 
     227         762 :         i = 0;
     228      124356 :         while (i < data_source_len) {
     229             :                 /* looking for NAME= */
     230             : 
     231      122832 :                 if (data_source[i] == '\0') {
     232           0 :                         break;
     233             :                 }
     234             : 
     235      122832 :                 if (data_source[i] != '=') {
     236      120419 :                         ++i;
     237      120419 :                         continue;
     238             :                 }
     239             : 
     240        2413 :                 valstart = ++i;
     241             : 
     242             :                 /* now we're looking for VALUE; or just VALUE<NUL> */
     243        2413 :                 semi = -1;
     244        2413 :                 n_semicolumns = 0;
     245       36074 :                 while (i < data_source_len) {
     246       32901 :                         if (data_source[i] == '\0') {
     247           0 :                                 semi = i++;
     248           0 :                                 break;
     249             :                         }
     250       32901 :                         if (data_source[i] == ';') {
     251        1653 :                                 if ((i + 1 >= data_source_len) || data_source[i+1] != ';') {
     252        1653 :                                         semi = i++;
     253        1653 :                                         break;
     254             :                                 } else {
     255           0 :                                         n_semicolumns++; 
     256           0 :                                         i += 2;
     257           0 :                                         continue;
     258             :                                 }
     259             :                         }
     260       31248 :                         ++i;
     261             :                 }
     262             : 
     263        2413 :                 if (semi == -1) {
     264         760 :                         semi = i;
     265             :                 }
     266             : 
     267             :                 /* find the entry in the array */
     268        2413 :                 nlen = valstart - optstart - 1;
     269       10022 :                 for (j = 0; j < nparams; j++) {
     270        9020 :                         if (0 == strncmp(data_source + optstart, parsed[j].optname, nlen) && parsed[j].optname[nlen] == '\0') {
     271             :                                 /* got a match */
     272        1411 :                                 if (parsed[j].freeme) {
     273           6 :                                         efree(parsed[j].optval);
     274             :                                 }
     275             : 
     276        1411 :                                 if (n_semicolumns == 0) {
     277        1411 :                                         parsed[j].optval = estrndup(data_source + valstart, semi - valstart - n_semicolumns);
     278             :                                 } else {
     279           0 :                                         int vlen = semi - valstart;
     280           0 :                                         const char *orig_val = data_source + valstart;
     281           0 :                                         char *new_val  = (char *) emalloc(vlen - n_semicolumns + 1);
     282             :                                 
     283           0 :                                         parsed[j].optval = new_val;
     284             : 
     285           0 :                                         while (vlen && *orig_val) {
     286           0 :                                                 *new_val = *orig_val;
     287           0 :                                                 new_val++;
     288             : 
     289           0 :                                                 if (*orig_val == ';') {
     290           0 :                                                         orig_val+=2; 
     291           0 :                                                         vlen-=2;
     292             :                                                 } else {
     293           0 :                                                         orig_val++;
     294           0 :                                                         vlen--;
     295             :                                                 }
     296             :                                         }
     297           0 :                                         *new_val = '\0';
     298             :                                 }
     299             : 
     300        1411 :                                 parsed[j].freeme = 1;
     301        1411 :                                 ++n_matches;
     302        1411 :                                 break;
     303             :                         }
     304             :                 }
     305             : 
     306        4826 :                 while (i < data_source_len && isspace(data_source[i])) {
     307           0 :                         i++;
     308             :                 }
     309             : 
     310        2413 :                 optstart = i;
     311             :         }
     312             : 
     313         762 :         return n_matches;
     314             : }
     315             : 
     316             : static const char digit_vec[] = "0123456789";
     317          14 : PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC)
     318             : {
     319             :         char buffer[65];
     320          14 :         char outbuf[65] = "";
     321             :         register char *p;
     322             :         long long_val;
     323          14 :         char *dst = outbuf;
     324             : 
     325          14 :         if (i64 < 0) {
     326           0 :                 i64 = -i64;
     327           0 :                 *dst++ = '-';
     328             :         }
     329             : 
     330          14 :         if (i64 == 0) {
     331           8 :                 *dst++ = '0';
     332           8 :                 *dst++ = '\0';
     333           8 :                 return estrdup(outbuf);
     334             :         }
     335             : 
     336           6 :         p = &buffer[sizeof(buffer)-1];
     337           6 :         *p = '\0';
     338             : 
     339          12 :         while ((pdo_uint64_t)i64 > (pdo_uint64_t)LONG_MAX) {
     340           0 :                 pdo_uint64_t quo = (pdo_uint64_t)i64 / (unsigned int)10;
     341           0 :                 unsigned int rem = (unsigned int)(i64 - quo*10U);
     342           0 :                 *--p = digit_vec[rem];
     343           0 :                 i64 = (pdo_int64_t)quo;
     344             :         }
     345           6 :         long_val = (long)i64;
     346          27 :         while (long_val != 0) {
     347          15 :                 long quo = long_val / 10;
     348          15 :                 *--p = digit_vec[(unsigned int)(long_val - quo * 10)];
     349          15 :                 long_val = quo;
     350             :         }
     351          21 :         while ((*dst++ = *p++) != 0)
     352             :                 ;
     353           6 :         *dst = '\0';
     354           6 :         return estrdup(outbuf);
     355             : }
     356             : 
     357             : /* {{{ PHP_MINIT_FUNCTION */
     358       21257 : PHP_MINIT_FUNCTION(pdo)
     359             : {
     360             :         zend_class_entry ce;
     361             : 
     362       21257 :         spl_ce_RuntimeException = NULL;
     363             : 
     364       21257 :         if (FAILURE == pdo_sqlstate_init_error_table()) {
     365           0 :                 return FAILURE;
     366             :         }
     367             : 
     368       21257 :         zend_hash_init(&pdo_driver_hash, 0, NULL, NULL, 1);
     369             : 
     370       21257 :         le_ppdo = zend_register_list_destructors_ex(NULL, php_pdo_pdbh_dtor,
     371             :                 "PDO persistent database", module_number);
     372             : 
     373       21257 :         INIT_CLASS_ENTRY(ce, "PDOException", NULL);
     374             : 
     375       21257 :         pdo_exception_ce = zend_register_internal_class_ex(&ce, php_pdo_get_exception_base(0 TSRMLS_CC), NULL TSRMLS_CC);
     376             : 
     377       21257 :         zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
     378             : 
     379       21257 :         pdo_dbh_init(TSRMLS_C);
     380       21257 :         pdo_stmt_init(TSRMLS_C);
     381             : 
     382       21257 :         return SUCCESS;
     383             : }
     384             : /* }}} */
     385             : 
     386             : /* {{{ PHP_MSHUTDOWN_FUNCTION */
     387       21290 : PHP_MSHUTDOWN_FUNCTION(pdo)
     388             : {
     389       21290 :         zend_hash_destroy(&pdo_driver_hash);
     390       21290 :         pdo_sqlstate_fini_error_table();
     391       21290 :         return SUCCESS;
     392             : }
     393             : /* }}} */
     394             : 
     395             : /* {{{ PHP_MINFO_FUNCTION */
     396         150 : PHP_MINFO_FUNCTION(pdo)
     397             : {
     398             :         HashPosition pos;
     399         150 :         char *drivers = NULL, *ldrivers = estrdup("");
     400             :         pdo_driver_t **pdriver;
     401             :         
     402         150 :         php_info_print_table_start();
     403         150 :         php_info_print_table_header(2, "PDO support", "enabled");
     404             : 
     405         150 :         zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
     406        1350 :         while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
     407        1050 :                 spprintf(&drivers, 0, "%s, %s", ldrivers, (*pdriver)->driver_name);
     408        1050 :                 zend_hash_move_forward_ex(&pdo_driver_hash, &pos);
     409        1050 :                 efree(ldrivers);
     410        1050 :                 ldrivers = drivers;
     411             :         }
     412             :         
     413         150 :         php_info_print_table_row(2, "PDO drivers", drivers ? drivers+2 : "");
     414             : 
     415         150 :         if (drivers) {
     416         150 :                 efree(drivers);
     417             :         } else {
     418           0 :                 efree(ldrivers);
     419             :         }
     420             : 
     421         150 :         php_info_print_table_end();
     422             : 
     423         150 : }
     424             : /* }}} */
     425             : 
     426             : /*
     427             :  * Local variables:
     428             :  * tab-width: 4
     429             :  * c-basic-offset: 4
     430             :  * End:
     431             :  * vim600: noet sw=4 ts=4 fdm=marker
     432             :  * vim<600: noet sw=4 ts=4
     433             :  */

Generated by: LCOV version 1.10

Generated at Tue, 22 Jul 2014 01:33:15 +0000 (2 days ago)

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