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: 2014-12-13 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-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_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     2041578 : PDO_API zend_class_entry *php_pdo_get_dbh_ce(void) /* {{{ */
      61             : {
      62     2041578 :         return pdo_dbh_ce;
      63             : }
      64             : /* }}} */
      65             : 
      66          80 : PDO_API zend_class_entry *php_pdo_get_exception(void) /* {{{ */
      67             : {
      68          80 :         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       20658 : PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC) /* {{{ */
      81             : {
      82             : #if defined(HAVE_SPL)
      83       20658 :         if (!root) {
      84       20622 :                 if (!spl_ce_RuntimeException) {
      85             :                         zend_class_entry *pce;
      86             : 
      87       41244 :                         if ((pce = zend_hash_str_find_ptr(CG(class_table), "runtimeexception", sizeof("RuntimeException") - 1))) {
      88       20622 :                                 spl_ce_RuntimeException = pce;
      89       20622 :                                 return pce;
      90             :                         }
      91             :                 } else {
      92           0 :                         return spl_ce_RuntimeException;
      93             :                 }
      94             :         }
      95             : #endif
      96          36 :         return zend_exception_get_default(TSRMLS_C);
      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             : #if ZEND_MODULE_API_NO >= 20050922
     144             :         STANDARD_MODULE_HEADER_EX, NULL,
     145             :         pdo_deps,
     146             : #else
     147             :         STANDARD_MODULE_HEADER,
     148             : #endif
     149             :         "PDO",
     150             :         pdo_functions,
     151             :         PHP_MINIT(pdo),
     152             :         PHP_MSHUTDOWN(pdo),
     153             :         NULL,
     154             :         NULL,
     155             :         PHP_MINFO(pdo),
     156             :         "1.0.4dev",
     157             :         PHP_MODULE_GLOBALS(pdo),
     158             :         PHP_GINIT(pdo),
     159             :         NULL,
     160             :         NULL,
     161             :         STANDARD_MODULE_PROPERTIES_EX
     162             : };
     163             : /* }}} */
     164             : 
     165             : /* TODO: visit persistent handles: for each persistent statement handle,
     166             :  * remove bound parameter associations */
     167             : 
     168             : #ifdef COMPILE_DL_PDO
     169             : ZEND_GET_MODULE(pdo)
     170             : #endif
     171             : 
     172             : /* {{{ PHP_GINIT_FUNCTION */
     173       20622 : static PHP_GINIT_FUNCTION(pdo)
     174             : {
     175       20622 :         pdo_globals->global_value = 0;
     176       20622 : }
     177             : /* }}} */
     178             : 
     179      123732 : PDO_API int php_pdo_register_driver(pdo_driver_t *driver) /* {{{ */
     180             : {
     181      123732 :         if (driver->api_version != PDO_DRIVER_API) {
     182           0 :                 zend_error(E_ERROR, "PDO: driver %s requires PDO API version %pd; this is PDO version %d",
     183             :                         driver->driver_name, driver->api_version, PDO_DRIVER_API);
     184           0 :                 return FAILURE;
     185             :         }
     186      123732 :         if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
     187           0 :                 zend_error(E_ERROR, "You MUST load PDO before loading any PDO drivers");
     188           0 :                 return FAILURE; /* NOTREACHED */
     189             :         }
     190             : 
     191      247464 :         return zend_hash_str_add_ptr(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len, driver) != NULL;
     192             : }
     193             : /* }}} */
     194             : 
     195      123936 : PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver) /* {{{ */
     196             : {
     197      123936 :         if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
     198           0 :                 return;
     199             :         }
     200             : 
     201      123936 :         zend_hash_str_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
     202             : }
     203             : /* }}} */
     204             : 
     205        1078 : pdo_driver_t *pdo_find_driver(const char *name, int namelen) /* {{{ */
     206             : {
     207        2156 :         return zend_hash_str_find_ptr(&pdo_driver_hash, (char*)name, namelen);
     208             : }
     209             : /* }}} */
     210             : 
     211         617 : 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) /* {{{ */
     212             : {
     213             :         int i, j;
     214         617 :         int valstart = -1;
     215         617 :         int semi = -1;
     216         617 :         int optstart = 0;
     217             :         int nlen;
     218         617 :         int n_matches = 0;
     219         617 :         int n_semicolumns = 0;
     220             : 
     221         617 :         i = 0;
     222      121943 :         while (i < data_source_len) {
     223             :                 /* looking for NAME= */
     224             : 
     225      120709 :                 if (data_source[i] == '\0') {
     226           0 :                         break;
     227             :                 }
     228             : 
     229      120709 :                 if (data_source[i] != '=') {
     230      118585 :                         ++i;
     231      118585 :                         continue;
     232             :                 }
     233             : 
     234        2124 :                 valstart = ++i;
     235             : 
     236             :                 /* now we're looking for VALUE; or just VALUE<NUL> */
     237        2124 :                 semi = -1;
     238        2124 :                 n_semicolumns = 0;
     239       31779 :                 while (i < data_source_len) {
     240       29040 :                         if (data_source[i] == '\0') {
     241           0 :                                 semi = i++;
     242           0 :                                 break;
     243             :                         }
     244       29040 :                         if (data_source[i] == ';') {
     245        1509 :                                 if ((i + 1 >= data_source_len) || data_source[i+1] != ';') {
     246        1509 :                                         semi = i++;
     247        1509 :                                         break;
     248             :                                 } else {
     249           0 :                                         n_semicolumns++; 
     250           0 :                                         i += 2;
     251           0 :                                         continue;
     252             :                                 }
     253             :                         }
     254       27531 :                         ++i;
     255             :                 }
     256             : 
     257        2124 :                 if (semi == -1) {
     258         615 :                         semi = i;
     259             :                 }
     260             : 
     261             :                 /* find the entry in the array */
     262        2124 :                 nlen = valstart - optstart - 1;
     263        9633 :                 for (j = 0; j < nparams; j++) {
     264        8631 :                         if (0 == strncmp(data_source + optstart, parsed[j].optname, nlen) && parsed[j].optname[nlen] == '\0') {
     265             :                                 /* got a match */
     266        1122 :                                 if (parsed[j].freeme) {
     267           6 :                                         efree(parsed[j].optval);
     268             :                                 }
     269             : 
     270        1122 :                                 if (n_semicolumns == 0) {
     271        1122 :                                         parsed[j].optval = estrndup(data_source + valstart, semi - valstart - n_semicolumns);
     272             :                                 } else {
     273           0 :                                         int vlen = semi - valstart;
     274           0 :                                         const char *orig_val = data_source + valstart;
     275           0 :                                         char *new_val  = (char *) emalloc(vlen - n_semicolumns + 1);
     276             :                                 
     277           0 :                                         parsed[j].optval = new_val;
     278             : 
     279           0 :                                         while (vlen && *orig_val) {
     280           0 :                                                 *new_val = *orig_val;
     281           0 :                                                 new_val++;
     282             : 
     283           0 :                                                 if (*orig_val == ';') {
     284           0 :                                                         orig_val+=2; 
     285           0 :                                                         vlen-=2;
     286             :                                                 } else {
     287           0 :                                                         orig_val++;
     288           0 :                                                         vlen--;
     289             :                                                 }
     290             :                                         }
     291           0 :                                         *new_val = '\0';
     292             :                                 }
     293             : 
     294        1122 :                                 parsed[j].freeme = 1;
     295        1122 :                                 ++n_matches;
     296        1122 :                                 break;
     297             :                         }
     298             :                 }
     299             : 
     300        4248 :                 while (i < data_source_len && isspace(data_source[i])) {
     301           0 :                         i++;
     302             :                 }
     303             : 
     304        2124 :                 optstart = i;
     305             :         }
     306             : 
     307         617 :         return n_matches;
     308             : }
     309             : /* }}} */
     310             : 
     311             : static const char digit_vec[] = "0123456789";
     312          14 : PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC) /* {{{ */
     313             : {
     314             :         char buffer[65];
     315          14 :         char outbuf[65] = "";
     316             :         register char *p;
     317             :         zend_long long_val;
     318          14 :         char *dst = outbuf;
     319             : 
     320          14 :         if (i64 < 0) {
     321           0 :                 i64 = -i64;
     322           0 :                 *dst++ = '-';
     323             :         }
     324             : 
     325          14 :         if (i64 == 0) {
     326           8 :                 *dst++ = '0';
     327           8 :                 *dst++ = '\0';
     328           8 :                 return estrdup(outbuf);
     329             :         }
     330             : 
     331           6 :         p = &buffer[sizeof(buffer)-1];
     332           6 :         *p = '\0';
     333             : 
     334          12 :         while ((pdo_uint64_t)i64 > (pdo_uint64_t)ZEND_LONG_MAX) {
     335           0 :                 pdo_uint64_t quo = (pdo_uint64_t)i64 / (unsigned int)10;
     336           0 :                 unsigned int rem = (unsigned int)(i64 - quo*10U);
     337           0 :                 *--p = digit_vec[rem];
     338           0 :                 i64 = (pdo_int64_t)quo;
     339             :         }
     340           6 :         long_val = (zend_long)i64;
     341          27 :         while (long_val != 0) {
     342          15 :                 zend_long quo = long_val / 10;
     343          15 :                 *--p = digit_vec[(unsigned int)(long_val - quo * 10)];
     344          15 :                 long_val = quo;
     345             :         }
     346          21 :         while ((*dst++ = *p++) != 0)
     347             :                 ;
     348           6 :         *dst = '\0';
     349           6 :         return estrdup(outbuf);
     350             : }
     351             : /* }}} */
     352             : 
     353             : /* {{{ PHP_MINIT_FUNCTION */
     354       20622 : PHP_MINIT_FUNCTION(pdo)
     355             : {
     356             :         zend_class_entry ce;
     357             : 
     358       20622 :         spl_ce_RuntimeException = NULL;
     359             : 
     360       20622 :         if (FAILURE == pdo_sqlstate_init_error_table()) {
     361           0 :                 return FAILURE;
     362             :         }
     363             : 
     364       20622 :         zend_hash_init(&pdo_driver_hash, 0, NULL, NULL, 1);
     365             : 
     366       20622 :         le_ppdo = zend_register_list_destructors_ex(NULL, php_pdo_pdbh_dtor,
     367             :                 "PDO persistent database", module_number);
     368             : 
     369       20622 :         INIT_CLASS_ENTRY(ce, "PDOException", NULL);
     370             : 
     371       20622 :         pdo_exception_ce = zend_register_internal_class_ex(&ce, php_pdo_get_exception_base(0 TSRMLS_CC) TSRMLS_CC);
     372             : 
     373       20622 :         zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
     374             : 
     375       20622 :         pdo_dbh_init(TSRMLS_C);
     376       20622 :         pdo_stmt_init(TSRMLS_C);
     377             : 
     378       20622 :         return SUCCESS;
     379             : }
     380             : /* }}} */
     381             : 
     382             : /* {{{ PHP_MSHUTDOWN_FUNCTION */
     383       20656 : PHP_MSHUTDOWN_FUNCTION(pdo)
     384             : {
     385       20656 :         zend_hash_destroy(&pdo_driver_hash);
     386       20656 :         pdo_sqlstate_fini_error_table();
     387       20656 :         return SUCCESS;
     388             : }
     389             : /* }}} */
     390             : 
     391             : /* {{{ PHP_MINFO_FUNCTION */
     392         144 : PHP_MINFO_FUNCTION(pdo)
     393             : {
     394         144 :         char *drivers = NULL, *ldrivers = estrdup("");
     395             :         pdo_driver_t *pdriver;
     396             :         
     397         144 :         php_info_print_table_start();
     398         144 :         php_info_print_table_header(2, "PDO support", "enabled");
     399             : 
     400        1872 :         ZEND_HASH_FOREACH_PTR(&pdo_driver_hash, pdriver) {
     401         864 :                 spprintf(&drivers, 0, "%s, %s", ldrivers, pdriver->driver_name);
     402         864 :                 efree(ldrivers);
     403         864 :                 ldrivers = drivers;
     404             :         } ZEND_HASH_FOREACH_END();
     405             :         
     406         144 :         php_info_print_table_row(2, "PDO drivers", drivers ? drivers + 2 : "");
     407             : 
     408         144 :         if (drivers) {
     409         144 :                 efree(drivers);
     410             :         } else {
     411           0 :                 efree(ldrivers);
     412             :         }
     413             : 
     414         144 :         php_info_print_table_end();
     415             : 
     416         144 : }
     417             : /* }}} */
     418             : 
     419             : /*
     420             :  * Local variables:
     421             :  * tab-width: 4
     422             :  * c-basic-offset: 4
     423             :  * End:
     424             :  * vim600: noet sw=4 ts=4 fdm=marker
     425             :  * vim<600: noet sw=4 ts=4
     426             :  */

Generated by: LCOV version 1.10

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

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