Annotation of embedaddon/php/ext/pdo/pdo.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   +----------------------------------------------------------------------+
        !             3:   | PHP Version 5                                                        |
        !             4:   +----------------------------------------------------------------------+
        !             5:   | Copyright (c) 1997-2012 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: pdo.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            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: int php_pdo_list_entry(void)
        !            50: {
        !            51:        return le_ppdo;
        !            52: }
        !            53: 
        !            54: /* for exceptional circumstances */
        !            55: zend_class_entry *pdo_exception_ce;
        !            56: 
        !            57: PDO_API zend_class_entry *php_pdo_get_dbh_ce(void)
        !            58: {
        !            59:        return pdo_dbh_ce;
        !            60: }
        !            61: 
        !            62: PDO_API zend_class_entry *php_pdo_get_exception(void)
        !            63: {
        !            64:        return pdo_exception_ce;
        !            65: }
        !            66: 
        !            67: PDO_API char *php_pdo_str_tolower_dup(const char *src, int len)
        !            68: {
        !            69:        char *dest = emalloc(len + 1);
        !            70:        zend_str_tolower_copy(dest, src, len);
        !            71:        return dest;
        !            72: }
        !            73: 
        !            74: 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:        if (!root) {
        !            78:                if (!spl_ce_RuntimeException) {
        !            79:                        zend_class_entry **pce;
        !            80: 
        !            81:                        if (zend_hash_find(CG(class_table), "runtimeexception", sizeof("RuntimeException"), (void **) &pce) == SUCCESS) {
        !            82:                                spl_ce_RuntimeException = *pce;
        !            83:                                return *pce;
        !            84:                        }
        !            85:                } else {
        !            86:                        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:        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: PHP_FUNCTION(pdo_drivers)
        !           102: {
        !           103:        HashPosition pos;
        !           104:        pdo_driver_t **pdriver;
        !           105: 
        !           106:        if (zend_parse_parameters_none() == FAILURE) {
        !           107:                return;
        !           108:        }
        !           109:        
        !           110:        array_init(return_value);
        !           111: 
        !           112:        zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
        !           113:        while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
        !           114:                add_next_index_stringl(return_value, (char*)(*pdriver)->driver_name, (*pdriver)->driver_name_len, 1);
        !           115:                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: static PHP_GINIT_FUNCTION(pdo)
        !           176: {
        !           177:        pdo_globals->global_value = 0;
        !           178: }
        !           179: /* }}} */
        !           180: 
        !           181: PDO_API int php_pdo_register_driver(pdo_driver_t *driver)
        !           182: {
        !           183:        if (driver->api_version != PDO_DRIVER_API) {
        !           184:                zend_error(E_ERROR, "PDO: driver %s requires PDO API version %ld; this is PDO version %d",
        !           185:                        driver->driver_name, driver->api_version, PDO_DRIVER_API);
        !           186:                return FAILURE;
        !           187:        }
        !           188:        if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
        !           189:                zend_error(E_ERROR, "You MUST load PDO before loading any PDO drivers");
        !           190:                return FAILURE; /* NOTREACHED */
        !           191:        }
        !           192: 
        !           193:        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: PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver)
        !           198: {
        !           199:        if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
        !           200:                return;
        !           201:        }
        !           202: 
        !           203:        zend_hash_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
        !           204: }
        !           205: 
        !           206: pdo_driver_t *pdo_find_driver(const char *name, int namelen)
        !           207: {
        !           208:        pdo_driver_t **driver = NULL;
        !           209:        
        !           210:        zend_hash_find(&pdo_driver_hash, (char*)name, namelen, (void**)&driver);
        !           211: 
        !           212:        return driver ? *driver : NULL;
        !           213: }
        !           214: 
        !           215: 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:        int valstart = -1;
        !           221:        int semi = -1;
        !           222:        int optstart = 0;
        !           223:        int nlen;
        !           224:        int n_matches = 0;
        !           225:        int n_semicolumns = 0;
        !           226: 
        !           227:        i = 0;
        !           228:        while (i < data_source_len) {
        !           229:                /* looking for NAME= */
        !           230: 
        !           231:                if (data_source[i] == '\0') {
        !           232:                        break;
        !           233:                }
        !           234: 
        !           235:                if (data_source[i] != '=') {
        !           236:                        ++i;
        !           237:                        continue;
        !           238:                }
        !           239: 
        !           240:                valstart = ++i;
        !           241: 
        !           242:                /* now we're looking for VALUE; or just VALUE<NUL> */
        !           243:                semi = -1;
        !           244:                n_semicolumns = 0;
        !           245:                while (i < data_source_len) {
        !           246:                        if (data_source[i] == '\0') {
        !           247:                                semi = i++;
        !           248:                                break;
        !           249:                        }
        !           250:                        if (data_source[i] == ';') {
        !           251:                                if ((i + 1 >= data_source_len) || data_source[i+1] != ';') {
        !           252:                                        semi = i++;
        !           253:                                        break;
        !           254:                                } else {
        !           255:                                        n_semicolumns++; 
        !           256:                                        i += 2;
        !           257:                                        continue;
        !           258:                                }
        !           259:                        }
        !           260:                        ++i;
        !           261:                }
        !           262: 
        !           263:                if (semi == -1) {
        !           264:                        semi = i;
        !           265:                }
        !           266: 
        !           267:                /* find the entry in the array */
        !           268:                nlen = valstart - optstart - 1;
        !           269:                for (j = 0; j < nparams; j++) {
        !           270:                        if (0 == strncmp(data_source + optstart, parsed[j].optname, nlen) && parsed[j].optname[nlen] == '\0') {
        !           271:                                /* got a match */
        !           272:                                if (parsed[j].freeme) {
        !           273:                                        efree(parsed[j].optval);
        !           274:                                }
        !           275: 
        !           276:                                if (n_semicolumns == 0) {
        !           277:                                        parsed[j].optval = estrndup(data_source + valstart, semi - valstart - n_semicolumns);
        !           278:                                } else {
        !           279:                                        int vlen = semi - valstart;
        !           280:                                        char *orig_val = data_source + valstart;
        !           281:                                        char *new_val  = (char *) emalloc(vlen - n_semicolumns + 1);
        !           282:                                
        !           283:                                        parsed[j].optval = new_val;
        !           284: 
        !           285:                                        while (vlen && *orig_val) {
        !           286:                                                *new_val = *orig_val;
        !           287:                                                new_val++;
        !           288: 
        !           289:                                                if (*orig_val == ';') {
        !           290:                                                        orig_val+=2; 
        !           291:                                                        vlen-=2;
        !           292:                                                } else {
        !           293:                                                        orig_val++;
        !           294:                                                        vlen--;
        !           295:                                                }
        !           296:                                        }
        !           297:                                        *new_val = '\0';
        !           298:                                }
        !           299: 
        !           300:                                parsed[j].freeme = 1;
        !           301:                                ++n_matches;
        !           302:                                break;
        !           303:                        }
        !           304:                }
        !           305: 
        !           306:                while (i < data_source_len && isspace(data_source[i])) {
        !           307:                        i++;
        !           308:                }
        !           309: 
        !           310:                optstart = i;
        !           311:        }
        !           312: 
        !           313:        return n_matches;
        !           314: }
        !           315: 
        !           316: static const char digit_vec[] = "0123456789";
        !           317: PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC)
        !           318: {
        !           319:        char buffer[65];
        !           320:        char outbuf[65] = "";
        !           321:        register char *p;
        !           322:        long long_val;
        !           323:        char *dst = outbuf;
        !           324: 
        !           325:        if (i64 < 0) {
        !           326:                i64 = -i64;
        !           327:                *dst++ = '-';
        !           328:        }
        !           329: 
        !           330:        if (i64 == 0) {
        !           331:                *dst++ = '0';
        !           332:                *dst++ = '\0';
        !           333:                return estrdup(outbuf);
        !           334:        }
        !           335: 
        !           336:        p = &buffer[sizeof(buffer)-1];
        !           337:        *p = '\0';
        !           338: 
        !           339:        while ((pdo_uint64_t)i64 > (pdo_uint64_t)LONG_MAX) {
        !           340:                pdo_uint64_t quo = (pdo_uint64_t)i64 / (unsigned int)10;
        !           341:                unsigned int rem = (unsigned int)(i64 - quo*10U);
        !           342:                *--p = digit_vec[rem];
        !           343:                i64 = (pdo_int64_t)quo;
        !           344:        }
        !           345:        long_val = (long)i64;
        !           346:        while (long_val != 0) {
        !           347:                long quo = long_val / 10;
        !           348:                *--p = digit_vec[(unsigned int)(long_val - quo * 10)];
        !           349:                long_val = quo;
        !           350:        }
        !           351:        while ((*dst++ = *p++) != 0)
        !           352:                ;
        !           353:        *dst = '\0';
        !           354:        return estrdup(outbuf);
        !           355: }
        !           356: 
        !           357: /* {{{ PHP_MINIT_FUNCTION */
        !           358: PHP_MINIT_FUNCTION(pdo)
        !           359: {
        !           360:        zend_class_entry ce;
        !           361: 
        !           362:        spl_ce_RuntimeException = NULL;
        !           363: 
        !           364:        if (FAILURE == pdo_sqlstate_init_error_table()) {
        !           365:                return FAILURE;
        !           366:        }
        !           367: 
        !           368:        zend_hash_init(&pdo_driver_hash, 0, NULL, NULL, 1);
        !           369: 
        !           370:        le_ppdo = zend_register_list_destructors_ex(NULL, php_pdo_pdbh_dtor,
        !           371:                "PDO persistent database", module_number);
        !           372: 
        !           373:        INIT_CLASS_ENTRY(ce, "PDOException", NULL);
        !           374: 
        !           375:        pdo_exception_ce = zend_register_internal_class_ex(&ce, php_pdo_get_exception_base(0 TSRMLS_CC), NULL TSRMLS_CC);
        !           376: 
        !           377:        zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
        !           378: 
        !           379:        pdo_dbh_init(TSRMLS_C);
        !           380:        pdo_stmt_init(TSRMLS_C);
        !           381: 
        !           382:        return SUCCESS;
        !           383: }
        !           384: /* }}} */
        !           385: 
        !           386: /* {{{ PHP_MSHUTDOWN_FUNCTION */
        !           387: PHP_MSHUTDOWN_FUNCTION(pdo)
        !           388: {
        !           389:        zend_hash_destroy(&pdo_driver_hash);
        !           390:        pdo_sqlstate_fini_error_table();
        !           391:        return SUCCESS;
        !           392: }
        !           393: /* }}} */
        !           394: 
        !           395: /* {{{ PHP_MINFO_FUNCTION */
        !           396: PHP_MINFO_FUNCTION(pdo)
        !           397: {
        !           398:        HashPosition pos;
        !           399:        char *drivers = NULL, *ldrivers = estrdup("");
        !           400:        pdo_driver_t **pdriver;
        !           401:        
        !           402:        php_info_print_table_start();
        !           403:        php_info_print_table_header(2, "PDO support", "enabled");
        !           404: 
        !           405:        zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
        !           406:        while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
        !           407:                spprintf(&drivers, 0, "%s, %s", ldrivers, (*pdriver)->driver_name);
        !           408:                zend_hash_move_forward_ex(&pdo_driver_hash, &pos);
        !           409:                efree(ldrivers);
        !           410:                ldrivers = drivers;
        !           411:        }
        !           412:        
        !           413:        php_info_print_table_row(2, "PDO drivers", drivers ? drivers+2 : "");
        !           414: 
        !           415:        if (drivers) {
        !           416:                efree(drivers);
        !           417:        } else {
        !           418:                efree(ldrivers);
        !           419:        }
        !           420: 
        !           421:        php_info_print_table_end();
        !           422: 
        !           423: }
        !           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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>