Return to mysqlnd_driver.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / mysqlnd |
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: */