Annotation of embedaddon/php/ext/mysqlnd/mysqlnd_driver.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   +----------------------------------------------------------------------+
        !             3:   | PHP Version 5                                                        |
        !             4:   +----------------------------------------------------------------------+
        !             5:   | Copyright (c) 2006-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:   | Authors: Andrey Hristov <andrey@mysql.com>                           |
        !            16:   |          Ulf Wendel <uwendel@mysql.com>                              |
        !            17:   |          Georg Richter <georg@mysql.com>                             |
        !            18:   +----------------------------------------------------------------------+
        !            19: */
        !            20: 
        !            21: /* $Id: mysqlnd.c 317989 2011-10-10 20:49:28Z andrey $ */
        !            22: #include "php.h"
        !            23: #include "mysqlnd.h"
        !            24: #include "mysqlnd_wireprotocol.h"
        !            25: #include "mysqlnd_priv.h"
        !            26: #include "mysqlnd_result.h"
        !            27: #include "mysqlnd_statistics.h"
        !            28: #include "mysqlnd_charset.h"
        !            29: #include "mysqlnd_debug.h"
        !            30: #include "mysqlnd_reverse_api.h"
        !            31: #include "mysqlnd_ext_plugin.h"
        !            32: 
        !            33: static zend_bool mysqlnd_library_initted = FALSE;
        !            34: 
        !            35: static struct st_mysqlnd_plugin_core mysqlnd_plugin_core =
        !            36: {
        !            37:        {
        !            38:                MYSQLND_PLUGIN_API_VERSION,
        !            39:                "mysqlnd",
        !            40:                MYSQLND_VERSION_ID,
        !            41:                MYSQLND_VERSION,
        !            42:                "PHP License 3.01",
        !            43:                "Andrey Hristov <andrey@mysql.com>,  Ulf Wendel <uwendel@mysql.com>, Georg Richter <georg@mysql.com>",
        !            44:                {
        !            45:                        NULL, /* will be filled later */
        !            46:                        mysqlnd_stats_values_names,
        !            47:                },
        !            48:                {
        !            49:                        NULL /* plugin shutdown */
        !            50:                }
        !            51:        }
        !            52: };
        !            53: 
        !            54: 
        !            55: /* {{{ mysqlnd_library_end */
        !            56: PHPAPI void mysqlnd_library_end(TSRMLS_D)
        !            57: {
        !            58:        if (mysqlnd_library_initted == TRUE) {
        !            59:                mysqlnd_plugin_subsystem_end(TSRMLS_C);
        !            60:                mysqlnd_stats_end(mysqlnd_global_stats);
        !            61:                mysqlnd_global_stats = NULL;
        !            62:                mysqlnd_library_initted = FALSE;
        !            63:                mysqlnd_reverse_api_end(TSRMLS_C);
        !            64:        }
        !            65: }
        !            66: /* }}} */
        !            67: 
        !            68: 
        !            69: /* {{{ mysqlnd_library_init */
        !            70: PHPAPI void mysqlnd_library_init(TSRMLS_D)
        !            71: {
        !            72:        if (mysqlnd_library_initted == FALSE) {
        !            73:                mysqlnd_library_initted = TRUE;
        !            74:                mysqlnd_conn_set_methods(&MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_conn));
        !            75:                mysqlnd_conn_data_set_methods(&MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_conn_data));
        !            76:                _mysqlnd_init_ps_subsystem();
        !            77:                /* Should be calloc, as mnd_calloc will reference LOCK_access*/
        !            78:                mysqlnd_stats_init(&mysqlnd_global_stats, STAT_LAST);
        !            79:                mysqlnd_plugin_subsystem_init(TSRMLS_C);
        !            80:                {
        !            81:                        mysqlnd_plugin_core.plugin_header.plugin_stats.values = mysqlnd_global_stats;
        !            82:                        mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_core TSRMLS_CC);
        !            83:                }
        !            84:                mysqlnd_example_plugin_register(TSRMLS_C);
        !            85:                mysqlnd_debug_trace_plugin_register(TSRMLS_C);
        !            86:                mysqlnd_register_builtin_authentication_plugins(TSRMLS_C);
        !            87: 
        !            88:                mysqlnd_reverse_api_init(TSRMLS_C);
        !            89:        }
        !            90: }
        !            91: /* }}} */
        !            92: 
        !            93: 
        !            94: /* {{{ mysqlnd_error_list_pdtor */
        !            95: static void
        !            96: mysqlnd_error_list_pdtor(void * pDest)
        !            97: {
        !            98:        MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
        !            99:        TSRMLS_FETCH();
        !           100:        DBG_ENTER("mysqlnd_error_list_pdtor");
        !           101:        if (element->error) {
        !           102:                mnd_pefree(element->error, TRUE);
        !           103:        }
        !           104:        DBG_VOID_RETURN;
        !           105: }
        !           106: /* }}} */
        !           107: 
        !           108: 
        !           109: /* {{{ mysqlnd_object_factory::get_connection */
        !           110: static MYSQLND *
        !           111: MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(zend_bool persistent TSRMLS_DC)
        !           112: {
        !           113:        size_t alloc_size_ret = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *);
        !           114:        size_t alloc_size_ret_data = sizeof(MYSQLND_CONN_DATA) + mysqlnd_plugin_count() * sizeof(void *);
        !           115:        MYSQLND * new_object;
        !           116:        MYSQLND_CONN_DATA * data;
        !           117: 
        !           118:        DBG_ENTER("mysqlnd_driver::get_connection");
        !           119:        DBG_INF_FMT("persistent=%u", persistent);
        !           120:        new_object = mnd_pecalloc(1, alloc_size_ret, persistent);
        !           121:        if (!new_object) {
        !           122:                DBG_RETURN(NULL);
        !           123:        }
        !           124:        new_object->data = mnd_pecalloc(1, alloc_size_ret_data, persistent);
        !           125:        if (!new_object->data) {
        !           126:                mnd_pefree(new_object, persistent);
        !           127:                DBG_RETURN(NULL);
        !           128:        }
        !           129:        new_object->persistent = persistent;
        !           130:        new_object->m = mysqlnd_conn_get_methods();
        !           131:        data = new_object->data;
        !           132: 
        !           133:        data->error_info = &(data->error_info_impl);
        !           134:        data->options = &(data->options_impl);
        !           135:        data->upsert_status = &(data->upsert_status_impl);
        !           136: 
        !           137:        data->persistent = persistent;
        !           138:        data->m = mysqlnd_conn_data_get_methods();
        !           139:        CONN_SET_STATE(data, CONN_ALLOCED);
        !           140:        data->m->get_reference(data TSRMLS_CC);
        !           141: 
        !           142:        if (PASS != data->m->init(data TSRMLS_CC)) {
        !           143:                new_object->m->dtor(new_object TSRMLS_CC);
        !           144:                DBG_RETURN(NULL);
        !           145:        }
        !           146: 
        !           147:        data->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
        !           148:        if (!data->error_info->error_list) {
        !           149:                new_object->m->dtor(new_object TSRMLS_CC);
        !           150:                DBG_RETURN(NULL);
        !           151:        } else {
        !           152:                zend_llist_init(data->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);
        !           153:        }
        !           154: 
        !           155:        DBG_RETURN(new_object);
        !           156: }
        !           157: /* }}} */
        !           158: 
        !           159: 
        !           160: /* {{{ mysqlnd_object_factory::clone_connection_object */
        !           161: static MYSQLND *
        !           162: MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object)(MYSQLND * to_be_cloned TSRMLS_DC)
        !           163: {
        !           164:        size_t alloc_size_ret = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *);
        !           165:        MYSQLND * new_object;
        !           166: 
        !           167:        DBG_ENTER("mysqlnd_driver::clone_connection_object");
        !           168:        DBG_INF_FMT("persistent=%u", to_be_cloned->persistent);
        !           169:        if (!to_be_cloned || !to_be_cloned->data) {
        !           170:                DBG_RETURN(NULL);
        !           171:        }
        !           172:        new_object = mnd_pecalloc(1, alloc_size_ret, to_be_cloned->persistent);
        !           173:        if (!new_object) {
        !           174:                DBG_RETURN(NULL);
        !           175:        }
        !           176:        new_object->persistent = to_be_cloned->persistent;
        !           177:        new_object->m = to_be_cloned->m;
        !           178: 
        !           179:        new_object->data = to_be_cloned->data->m->get_reference(to_be_cloned->data TSRMLS_CC);
        !           180:        if (!new_object->data) {
        !           181:                new_object->m->dtor(new_object TSRMLS_CC);
        !           182:                new_object = NULL;
        !           183:        }
        !           184:        DBG_RETURN(new_object);
        !           185: }
        !           186: /* }}} */
        !           187: 
        !           188: 
        !           189: /* {{{ mysqlnd_object_factory::get_prepared_statement */
        !           190: static MYSQLND_STMT *
        !           191: MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
        !           192: {
        !           193:        size_t alloc_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *);
        !           194:        MYSQLND_STMT * ret = mnd_pecalloc(1, alloc_size, conn->persistent);
        !           195:        MYSQLND_STMT_DATA * stmt = NULL;
        !           196: 
        !           197:        DBG_ENTER("mysqlnd_object_factory::get_prepared_statement");
        !           198:        do {
        !           199:                if (!ret) {
        !           200:                        break;
        !           201:                }
        !           202:                ret->m = mysqlnd_stmt_get_methods();
        !           203:                ret->persistent = conn->persistent;
        !           204: 
        !           205:                stmt = ret->data = mnd_pecalloc(1, sizeof(MYSQLND_STMT_DATA), conn->persistent);
        !           206:                DBG_INF_FMT("stmt=%p", stmt);
        !           207:                if (!stmt) {
        !           208:                        break;
        !           209:                }
        !           210:                stmt->persistent = conn->persistent;
        !           211:                stmt->error_info = &(stmt->error_info_impl);
        !           212:                stmt->upsert_status = &(stmt->upsert_status_impl);
        !           213:                stmt->state = MYSQLND_STMT_INITTED;
        !           214:                stmt->execute_cmd_buffer.length = 4096;
        !           215:                stmt->execute_cmd_buffer.buffer = mnd_pemalloc(stmt->execute_cmd_buffer.length, stmt->persistent);
        !           216:                if (!stmt->execute_cmd_buffer.buffer) {
        !           217:                        break;
        !           218:                }
        !           219: 
        !           220:                stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS;
        !           221:                /*
        !           222:                  Mark that we reference the connection, thus it won't be
        !           223:                  be destructed till there is open statements. The last statement
        !           224:                  or normal query result will close it then.
        !           225:                */
        !           226:                stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
        !           227:                stmt->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
        !           228:                if (!stmt->error_info->error_list) {
        !           229:                        break;
        !           230:                }
        !           231: 
        !           232:                zend_llist_init(stmt->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, conn->persistent);
        !           233: 
        !           234:                DBG_RETURN(ret);
        !           235:        } while (0);
        !           236: 
        !           237:        SET_OOM_ERROR(*conn->error_info);
        !           238:        if (ret) {
        !           239:                ret->m->dtor(ret, TRUE TSRMLS_CC);
        !           240:                ret = NULL;
        !           241:        }
        !           242:        DBG_RETURN(NULL);
        !           243: }
        !           244: /* }}} */
        !           245: 
        !           246: 
        !           247: /* {{{ mysqlnd_object_factory::get_io_channel */
        !           248: PHPAPI MYSQLND_NET *
        !           249: MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC)
        !           250: {
        !           251:        size_t alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *);
        !           252:        MYSQLND_NET * net = mnd_pecalloc(1, alloc_size, persistent);
        !           253: 
        !           254:        DBG_ENTER("mysqlnd_object_factory::get_io_channel");
        !           255:        DBG_INF_FMT("persistent=%u", persistent);
        !           256:        if (net) {
        !           257:                net->persistent = persistent;
        !           258:                net->m = *mysqlnd_net_get_methods();
        !           259: 
        !           260:                if (PASS != net->m.init(net, stats, error_info TSRMLS_CC)) {
        !           261:                        net->m.dtor(net, stats, error_info TSRMLS_CC);
        !           262:                        net = NULL;
        !           263:                }
        !           264:        }
        !           265:        DBG_RETURN(net);
        !           266: }
        !           267: /* }}} */
        !           268: 
        !           269: 
        !           270: /* {{{ mysqlnd_object_factory::get_protocol_decoder */
        !           271: PHPAPI MYSQLND_PROTOCOL *
        !           272: MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)(zend_bool persistent TSRMLS_DC)
        !           273: {
        !           274:        size_t alloc_size = sizeof(MYSQLND_PROTOCOL) + mysqlnd_plugin_count() * sizeof(void *);
        !           275:        MYSQLND_PROTOCOL *ret = mnd_pecalloc(1, alloc_size, persistent);
        !           276: 
        !           277:        DBG_ENTER("mysqlnd_object_factory::get_protocol_decoder");
        !           278:        DBG_INF_FMT("persistent=%u", persistent);
        !           279:        if (ret) {
        !           280:                ret->persistent = persistent;
        !           281:                ret->m = mysqlnd_mysqlnd_protocol_methods;
        !           282:        }
        !           283: 
        !           284:        DBG_RETURN(ret);
        !           285: }
        !           286: /* }}} */
        !           287: 
        !           288: 
        !           289: MYSQLND_CLASS_METHODS_START(mysqlnd_object_factory)
        !           290:        MYSQLND_METHOD(mysqlnd_object_factory, get_connection),
        !           291:        MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object),
        !           292:        MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement),
        !           293:        MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel),
        !           294:        MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)
        !           295: MYSQLND_CLASS_METHODS_END;
        !           296: 
        !           297: /*
        !           298:  * Local variables:
        !           299:  * tab-width: 4
        !           300:  * c-basic-offset: 4
        !           301:  * End:
        !           302:  * vim600: noet sw=4 ts=4 fdm=marker
        !           303:  * vim<600: noet sw=4 ts=4
        !           304:  */

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