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

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.2 ! misho       5:   | Copyright (c) 2006-2013 The PHP Group                                |
1.1       misho       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;
1.1.1.2 ! misho      99: #ifdef ZTS
1.1       misho     100:        TSRMLS_FETCH();
1.1.1.2 ! misho     101: #endif
1.1       misho     102:        DBG_ENTER("mysqlnd_error_list_pdtor");
                    103:        if (element->error) {
                    104:                mnd_pefree(element->error, TRUE);
                    105:        }
                    106:        DBG_VOID_RETURN;
                    107: }
                    108: /* }}} */
                    109: 
                    110: 
                    111: /* {{{ mysqlnd_object_factory::get_connection */
                    112: static MYSQLND *
                    113: MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(zend_bool persistent TSRMLS_DC)
                    114: {
                    115:        size_t alloc_size_ret = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *);
                    116:        size_t alloc_size_ret_data = sizeof(MYSQLND_CONN_DATA) + mysqlnd_plugin_count() * sizeof(void *);
                    117:        MYSQLND * new_object;
                    118:        MYSQLND_CONN_DATA * data;
                    119: 
                    120:        DBG_ENTER("mysqlnd_driver::get_connection");
                    121:        DBG_INF_FMT("persistent=%u", persistent);
                    122:        new_object = mnd_pecalloc(1, alloc_size_ret, persistent);
                    123:        if (!new_object) {
                    124:                DBG_RETURN(NULL);
                    125:        }
                    126:        new_object->data = mnd_pecalloc(1, alloc_size_ret_data, persistent);
                    127:        if (!new_object->data) {
                    128:                mnd_pefree(new_object, persistent);
                    129:                DBG_RETURN(NULL);
                    130:        }
                    131:        new_object->persistent = persistent;
                    132:        new_object->m = mysqlnd_conn_get_methods();
                    133:        data = new_object->data;
                    134: 
                    135:        data->error_info = &(data->error_info_impl);
                    136:        data->options = &(data->options_impl);
                    137:        data->upsert_status = &(data->upsert_status_impl);
                    138: 
                    139:        data->persistent = persistent;
                    140:        data->m = mysqlnd_conn_data_get_methods();
                    141:        CONN_SET_STATE(data, CONN_ALLOCED);
                    142:        data->m->get_reference(data TSRMLS_CC);
                    143: 
                    144:        if (PASS != data->m->init(data TSRMLS_CC)) {
                    145:                new_object->m->dtor(new_object TSRMLS_CC);
                    146:                DBG_RETURN(NULL);
                    147:        }
                    148: 
                    149:        data->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
                    150:        if (!data->error_info->error_list) {
                    151:                new_object->m->dtor(new_object TSRMLS_CC);
                    152:                DBG_RETURN(NULL);
                    153:        } else {
                    154:                zend_llist_init(data->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);
                    155:        }
                    156: 
                    157:        DBG_RETURN(new_object);
                    158: }
                    159: /* }}} */
                    160: 
                    161: 
                    162: /* {{{ mysqlnd_object_factory::clone_connection_object */
                    163: static MYSQLND *
                    164: MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object)(MYSQLND * to_be_cloned TSRMLS_DC)
                    165: {
                    166:        size_t alloc_size_ret = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *);
                    167:        MYSQLND * new_object;
                    168: 
                    169:        DBG_ENTER("mysqlnd_driver::clone_connection_object");
                    170:        DBG_INF_FMT("persistent=%u", to_be_cloned->persistent);
                    171:        if (!to_be_cloned || !to_be_cloned->data) {
                    172:                DBG_RETURN(NULL);
                    173:        }
                    174:        new_object = mnd_pecalloc(1, alloc_size_ret, to_be_cloned->persistent);
                    175:        if (!new_object) {
                    176:                DBG_RETURN(NULL);
                    177:        }
                    178:        new_object->persistent = to_be_cloned->persistent;
                    179:        new_object->m = to_be_cloned->m;
                    180: 
                    181:        new_object->data = to_be_cloned->data->m->get_reference(to_be_cloned->data TSRMLS_CC);
                    182:        if (!new_object->data) {
                    183:                new_object->m->dtor(new_object TSRMLS_CC);
                    184:                new_object = NULL;
                    185:        }
                    186:        DBG_RETURN(new_object);
                    187: }
                    188: /* }}} */
                    189: 
                    190: 
                    191: /* {{{ mysqlnd_object_factory::get_prepared_statement */
                    192: static MYSQLND_STMT *
                    193: MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
                    194: {
                    195:        size_t alloc_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *);
                    196:        MYSQLND_STMT * ret = mnd_pecalloc(1, alloc_size, conn->persistent);
                    197:        MYSQLND_STMT_DATA * stmt = NULL;
                    198: 
                    199:        DBG_ENTER("mysqlnd_object_factory::get_prepared_statement");
                    200:        do {
                    201:                if (!ret) {
                    202:                        break;
                    203:                }
                    204:                ret->m = mysqlnd_stmt_get_methods();
                    205:                ret->persistent = conn->persistent;
                    206: 
                    207:                stmt = ret->data = mnd_pecalloc(1, sizeof(MYSQLND_STMT_DATA), conn->persistent);
                    208:                DBG_INF_FMT("stmt=%p", stmt);
                    209:                if (!stmt) {
                    210:                        break;
                    211:                }
                    212:                stmt->persistent = conn->persistent;
                    213:                stmt->error_info = &(stmt->error_info_impl);
                    214:                stmt->upsert_status = &(stmt->upsert_status_impl);
                    215:                stmt->state = MYSQLND_STMT_INITTED;
                    216:                stmt->execute_cmd_buffer.length = 4096;
                    217:                stmt->execute_cmd_buffer.buffer = mnd_pemalloc(stmt->execute_cmd_buffer.length, stmt->persistent);
                    218:                if (!stmt->execute_cmd_buffer.buffer) {
                    219:                        break;
                    220:                }
                    221: 
                    222:                stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS;
                    223:                /*
                    224:                  Mark that we reference the connection, thus it won't be
                    225:                  be destructed till there is open statements. The last statement
                    226:                  or normal query result will close it then.
                    227:                */
                    228:                stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
                    229:                stmt->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
                    230:                if (!stmt->error_info->error_list) {
                    231:                        break;
                    232:                }
                    233: 
                    234:                zend_llist_init(stmt->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, conn->persistent);
                    235: 
                    236:                DBG_RETURN(ret);
                    237:        } while (0);
                    238: 
                    239:        SET_OOM_ERROR(*conn->error_info);
                    240:        if (ret) {
                    241:                ret->m->dtor(ret, TRUE TSRMLS_CC);
                    242:                ret = NULL;
                    243:        }
                    244:        DBG_RETURN(NULL);
                    245: }
                    246: /* }}} */
                    247: 
                    248: 
                    249: /* {{{ mysqlnd_object_factory::get_io_channel */
                    250: PHPAPI MYSQLND_NET *
                    251: MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC)
                    252: {
                    253:        size_t alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *);
                    254:        MYSQLND_NET * net = mnd_pecalloc(1, alloc_size, persistent);
                    255: 
                    256:        DBG_ENTER("mysqlnd_object_factory::get_io_channel");
                    257:        DBG_INF_FMT("persistent=%u", persistent);
                    258:        if (net) {
                    259:                net->persistent = persistent;
                    260:                net->m = *mysqlnd_net_get_methods();
                    261: 
                    262:                if (PASS != net->m.init(net, stats, error_info TSRMLS_CC)) {
                    263:                        net->m.dtor(net, stats, error_info TSRMLS_CC);
                    264:                        net = NULL;
                    265:                }
                    266:        }
                    267:        DBG_RETURN(net);
                    268: }
                    269: /* }}} */
                    270: 
                    271: 
                    272: /* {{{ mysqlnd_object_factory::get_protocol_decoder */
                    273: PHPAPI MYSQLND_PROTOCOL *
                    274: MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)(zend_bool persistent TSRMLS_DC)
                    275: {
                    276:        size_t alloc_size = sizeof(MYSQLND_PROTOCOL) + mysqlnd_plugin_count() * sizeof(void *);
                    277:        MYSQLND_PROTOCOL *ret = mnd_pecalloc(1, alloc_size, persistent);
                    278: 
                    279:        DBG_ENTER("mysqlnd_object_factory::get_protocol_decoder");
                    280:        DBG_INF_FMT("persistent=%u", persistent);
                    281:        if (ret) {
                    282:                ret->persistent = persistent;
                    283:                ret->m = mysqlnd_mysqlnd_protocol_methods;
                    284:        }
                    285: 
                    286:        DBG_RETURN(ret);
                    287: }
                    288: /* }}} */
                    289: 
                    290: 
                    291: MYSQLND_CLASS_METHODS_START(mysqlnd_object_factory)
                    292:        MYSQLND_METHOD(mysqlnd_object_factory, get_connection),
                    293:        MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object),
                    294:        MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement),
                    295:        MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel),
                    296:        MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)
                    297: MYSQLND_CLASS_METHODS_END;
                    298: 
                    299: /*
                    300:  * Local variables:
                    301:  * tab-width: 4
                    302:  * c-basic-offset: 4
                    303:  * End:
                    304:  * vim600: noet sw=4 ts=4 fdm=marker
                    305:  * vim<600: noet sw=4 ts=4
                    306:  */

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