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

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