1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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 : | Author: Georg Richter <georg@php.net> |
16 : +----------------------------------------------------------------------+
17 :
18 : $Id: mysqli_prop.c 275985 2009-02-17 10:40:18Z johannes $
19 : */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include "config.h"
23 : #endif
24 :
25 : #include <signal.h>
26 :
27 : #include "php.h"
28 : #include "php_ini.h"
29 : #include "ext/standard/info.h"
30 : #include "php_mysqli.h"
31 :
32 : #define CHECK_STATUS(value) \
33 : if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \
34 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Property access is not allowed yet"); \
35 : ZVAL_NULL(*retval); \
36 : return SUCCESS; \
37 : } \
38 :
39 : #define MYSQLI_GET_MYSQL(statusval) \
40 : MYSQL *p; \
41 : ALLOC_ZVAL(*retval);\
42 : if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \
43 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name);\
44 : ZVAL_NULL(*retval);\
45 : return SUCCESS; \
46 : } else { \
47 : CHECK_STATUS(statusval);\
48 : p = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql;\
49 : }
50 :
51 : #define MYSQLI_GET_RESULT(statusval) \
52 : MYSQL_RES *p; \
53 : ALLOC_ZVAL(*retval);\
54 : if (!obj->ptr) { \
55 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name);\
56 : ZVAL_NULL(*retval);\
57 : return SUCCESS; \
58 : } else { \
59 : CHECK_STATUS(statusval);\
60 : p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \
61 : }
62 :
63 :
64 : #define MYSQLI_GET_STMT(statusval) \
65 : MYSQL_STMT *p; \
66 : ALLOC_ZVAL(*retval);\
67 : if (!obj->ptr) { \
68 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name);\
69 : ZVAL_NULL(*retval);\
70 : return SUCCESS; \
71 : } else { \
72 : CHECK_STATUS(statusval);\
73 : p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt;\
74 : }
75 :
76 : #define MYSQLI_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type)\
77 : static int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \
78 : {\
79 : __ret_type l;\
80 : __get_type;\
81 : if (!p) {\
82 : ZVAL_NULL(*retval);\
83 : } else {\
84 : l = (__ret_type)__int_func(p);\
85 : if (l < LONG_MAX) {\
86 : ZVAL_LONG(*retval, l);\
87 : } else { \
88 : char *ret; \
89 : int ret_len = spprintf(&ret, 0, MYSQLI_LLU_SPEC, (my_ulonglong)l); \
90 : ZVAL_STRINGL(*retval, ret, ret_len, 0); \
91 : } \
92 : }\
93 : return SUCCESS;\
94 : }
95 :
96 : #define MYSQLI_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\
97 : static int __func(mysqli_object *obj, zval **retval TSRMLS_DC)\
98 : {\
99 : char *c;\
100 : __get_type;\
101 : if (!p) {\
102 : ZVAL_NULL(*retval);\
103 : } else {\
104 : c = (char *)__int_func(p);\
105 : if (!c) {\
106 : ZVAL_NULL(*retval);\
107 : } else {\
108 : ZVAL_STRING(*retval, c, 1);\
109 : }\
110 : }\
111 : return SUCCESS;\
112 : }
113 :
114 : /* {{{ property link_client_version_read */
115 : static int link_client_version_read(mysqli_object *obj, zval **retval TSRMLS_DC)
116 1 : {
117 1 : ALLOC_ZVAL(*retval);
118 1 : ZVAL_LONG(*retval, MYSQL_VERSION_ID);
119 1 : return SUCCESS;
120 : }
121 : /* }}} */
122 :
123 : /* {{{ property link_client_info_read */
124 : static int link_client_info_read(mysqli_object *obj, zval **retval TSRMLS_DC)
125 0 : {
126 0 : ALLOC_ZVAL(*retval);
127 0 : CHECK_STATUS(MYSQLI_STATUS_INITIALIZED);
128 0 : ZVAL_STRING(*retval, MYSQL_SERVER_VERSION, 1);
129 0 : return SUCCESS;
130 : }
131 : /* }}} */
132 :
133 : /* {{{ property link_connect_errno_read */
134 : static int link_connect_errno_read(mysqli_object *obj, zval **retval TSRMLS_DC)
135 0 : {
136 0 : ALLOC_ZVAL(*retval);
137 0 : ZVAL_LONG(*retval, (long)MyG(error_no));
138 0 : return SUCCESS;
139 : }
140 : /* }}} */
141 :
142 : /* {{{ property link_connect_error_read */
143 : static int link_connect_error_read(mysqli_object *obj, zval **retval TSRMLS_DC)
144 1 : {
145 1 : ALLOC_ZVAL(*retval);
146 1 : if (MyG(error_msg)) {
147 1 : ZVAL_STRING(*retval, MyG(error_msg), 1);
148 : } else {
149 0 : ZVAL_NULL(*retval);
150 : }
151 1 : return SUCCESS;
152 : }
153 : /* }}} */
154 :
155 : /* {{{ property link_affected_rows_read */
156 : static int link_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC)
157 0 : {
158 : MY_MYSQL *mysql;
159 : my_ulonglong rc;
160 :
161 0 : ALLOC_ZVAL(*retval);
162 :
163 0 : mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
164 :
165 0 : if (!mysql) {
166 0 : ZVAL_NULL(*retval);
167 : } else {
168 0 : CHECK_STATUS(MYSQLI_STATUS_VALID);
169 :
170 0 : rc = mysql_affected_rows(mysql->mysql);
171 :
172 0 : if (rc == (my_ulonglong)-1) {
173 0 : ZVAL_LONG(*retval, -1);
174 0 : return SUCCESS;
175 : }
176 :
177 0 : if (rc < LONG_MAX) {
178 0 : ZVAL_LONG(*retval, rc);
179 : } else {
180 : char *ret;
181 0 : int l = spprintf(&ret, 0, MYSQLI_LLU_SPEC, (my_ulonglong) rc);
182 0 : ZVAL_STRINGL(*retval, ret, l, 0);
183 : }
184 : }
185 0 : return SUCCESS;
186 : }
187 : /* }}} */
188 :
189 : /* link properties */
190 9 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), ulong);
191 3 : MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED));
192 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_field_count_read, mysql_field_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong);
193 0 : MYSQLI_MAP_PROPERTY_FUNC_STRING(link_host_info_read, mysql_get_host_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID));
194 0 : MYSQLI_MAP_PROPERTY_FUNC_STRING(link_info_read, mysql_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID));
195 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_insert_id_read, mysql_insert_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), my_ulonglong);
196 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_protocol_version_read, mysql_get_proto_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong);
197 0 : MYSQLI_MAP_PROPERTY_FUNC_STRING(link_server_info_read, mysql_get_server_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID));
198 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong);
199 1 : MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID));
200 1 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong);
201 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong);
202 : /* result properties */
203 :
204 : /* {{{ property result_type_read */
205 : static int result_type_read(mysqli_object *obj, zval **retval TSRMLS_DC)
206 0 : {
207 : MYSQL_RES *p;
208 :
209 0 : ALLOC_ZVAL(*retval);
210 0 : CHECK_STATUS(MYSQLI_STATUS_VALID);
211 0 : p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
212 :
213 0 : if (!p) {
214 0 : ZVAL_NULL(*retval);
215 : } else {
216 0 : ZVAL_LONG(*retval, (p->data) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
217 : }
218 0 : return SUCCESS;
219 : }
220 : /* }}} */
221 :
222 : /* {{{ property result_lengths_read */
223 : static int result_lengths_read(mysqli_object *obj, zval **retval TSRMLS_DC)
224 0 : {
225 : MYSQL_RES *p;
226 :
227 0 : ALLOC_ZVAL(*retval);
228 :
229 0 : CHECK_STATUS(MYSQLI_STATUS_VALID);
230 0 : p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
231 0 : if (!p || !p->field_count) {
232 0 : ZVAL_NULL(*retval);
233 : } else {
234 : ulong i;
235 : zval *l;
236 :
237 0 : array_init(*retval);
238 :
239 0 : for (i=0; i < p->field_count; i++) {
240 0 : MAKE_STD_ZVAL(l);
241 0 : ZVAL_LONG(l, p->lengths[i]);
242 0 : add_index_zval(*retval, i, l);
243 : }
244 : }
245 0 : return SUCCESS;
246 : }
247 : /* }}} */
248 :
249 :
250 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(result_current_field_read, mysql_field_tell, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), ulong);
251 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(result_field_count_read, mysql_num_fields, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), ulong);
252 2 : MYSQLI_MAP_PROPERTY_FUNC_LONG(result_num_rows_read, mysql_num_rows, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), my_ulonglong);
253 :
254 : /* statement properties */
255 :
256 : /* {{{ property stmt_id_read */
257 : static int stmt_id_read(mysqli_object *obj, zval **retval TSRMLS_DC)
258 0 : {
259 : MY_STMT *p;
260 :
261 0 : ALLOC_ZVAL(*retval);
262 0 : CHECK_STATUS(MYSQLI_STATUS_VALID);
263 :
264 0 : p = (MY_STMT*)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
265 :
266 0 : if (!p) {
267 0 : ZVAL_NULL(*retval);
268 : } else {
269 0 : ZVAL_LONG(*retval, p->stmt->stmt_id);
270 : }
271 0 : return SUCCESS;
272 : }
273 : /* }}} */
274 :
275 : /* {{{ property stmt_affected_rows_read */
276 : static int stmt_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC)
277 0 : {
278 : MY_STMT *p;
279 : my_ulonglong rc;
280 :
281 0 : ALLOC_ZVAL(*retval);
282 0 : CHECK_STATUS(MYSQLI_STATUS_VALID);
283 :
284 0 : p = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
285 :
286 0 : if (!p) {
287 0 : ZVAL_NULL(*retval);
288 : } else {
289 0 : rc = mysql_stmt_affected_rows(p->stmt);
290 :
291 0 : if (rc == (my_ulonglong)-1) {
292 0 : ZVAL_LONG(*retval, -1);
293 0 : return SUCCESS;
294 : }
295 :
296 0 : if (rc < LONG_MAX) {
297 0 : ZVAL_LONG(*retval, rc);
298 : } else {
299 : char *ret;
300 0 : int l = spprintf(&ret, 0, MYSQLI_LLU_SPEC, (my_ulonglong) rc);
301 0 : ZVAL_STRINGL(*retval, ret, l, 0);
302 : }
303 : }
304 0 : return SUCCESS;
305 : }
306 : /* }}} */
307 :
308 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong);
309 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong);
310 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong);
311 1 : MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_field_count_read, mysql_stmt_field_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong);
312 0 : MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_errno_read, mysql_stmt_errno, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED), ulong);
313 0 : MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_error_read, mysql_stmt_error, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED));
314 0 : MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_sqlstate_read, mysql_stmt_sqlstate, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED));
315 :
316 : /* }}} */
317 : mysqli_property_entry mysqli_link_property_entries[] = {
318 : {"affected_rows", link_affected_rows_read, NULL},
319 : {"client_info", link_client_info_read, NULL},
320 : {"client_version", link_client_version_read, NULL},
321 : {"connect_errno", link_connect_errno_read, NULL},
322 : {"connect_error", link_connect_error_read, NULL},
323 : {"errno", link_errno_read, NULL},
324 : {"error", link_error_read, NULL},
325 : {"field_count", link_field_count_read, NULL},
326 : {"host_info", link_host_info_read, NULL},
327 : {"info", link_info_read, NULL},
328 : {"insert_id", link_insert_id_read, NULL},
329 : {"server_info", link_server_info_read, NULL},
330 : {"server_version", link_server_version_read, NULL},
331 : {"sqlstate", link_sqlstate_read, NULL},
332 : {"protocol_version", link_protocol_version_read, NULL},
333 : {"thread_id", link_thread_id_read, NULL},
334 : {"warning_count", link_warning_count_read, NULL},
335 : {NULL, NULL, NULL}
336 : };
337 :
338 : mysqli_property_entry mysqli_result_property_entries[] = {
339 : {"current_field", result_current_field_read, NULL},
340 : {"field_count", result_field_count_read, NULL},
341 : {"lengths", result_lengths_read, NULL},
342 : {"num_rows", result_num_rows_read, NULL},
343 : {"type", result_type_read, NULL},
344 : {NULL, NULL, NULL}
345 : };
346 :
347 : mysqli_property_entry mysqli_stmt_property_entries[] = {
348 : {"affected_rows", stmt_affected_rows_read, NULL},
349 : {"insert_id", stmt_insert_id_read, NULL},
350 : {"num_rows", stmt_num_rows_read, NULL},
351 : {"param_count", stmt_param_count_read, NULL},
352 : {"field_count", stmt_field_count_read, NULL},
353 : {"errno", stmt_errno_read, NULL},
354 : {"error", stmt_error_read, NULL},
355 : {"sqlstate", stmt_sqlstate_read, NULL},
356 : {"id", stmt_id_read, NULL},
357 : {NULL, NULL, NULL}
358 : };
359 :
360 : /*
361 : * Local variables:
362 : * tab-width: 4
363 : * c-basic-offset: 4
364 : * End:
365 : * vim600: noet sw=4 ts=4 fdm=marker
366 : * vim<600: noet sw=4 ts=4
367 : */
|