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: 109 153 71.2 %
Date: 2015-05-21 Functions: 13 15 86.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:59:00 +0000 (3 days ago)

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