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>