root/ext/mysqlnd/mysqlnd_driver.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mysqlnd_library_end
  2. mysqlnd_library_init
  3. mysqlnd_error_list_pdtor
  4. MYSQLND_METHOD
  5. MYSQLND_METHOD
  6. MYSQLND_METHOD
  7. MYSQLND_METHOD

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

/* [<][>][^][v][top][bottom][index][help] */