Annotation of embedaddon/php/ext/mysqlnd/mysqlnd_driver.c, revision 1.1.1.1
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: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>