root/ext/mysqli/mysqli_warning.c

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

DEFINITIONS

This source file includes following definitions.
  1. php_clear_warnings
  2. php_new_warning
  3. php_get_warnings
  4. php_new_warning
  5. php_get_warnings
  6. PHP_METHOD
  7. mysqli_warning_message
  8. mysqli_warning_sqlstate
  9. mysqli_warning_errno
  10. PHP_METHOD

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 5                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-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   | Author: Georg Richter <georg@php.net>                                |
  16   +----------------------------------------------------------------------+
  17 
  18 */
  19 #ifdef HAVE_CONFIG_H
  20 #include "config.h"
  21 #endif
  22 
  23 #include <signal.h>
  24 
  25 #include "php.h"
  26 #include "php_ini.h"
  27 #include "ext/standard/info.h"
  28 #include "php_mysqli_structs.h"
  29 #include "mysqli_priv.h"
  30 
  31 /* Define these in the PHP5 tree to make merging easy process */
  32 #define ZSTR_DUPLICATE (1<<0)
  33 #define ZSTR_AUTOFREE  (1<<1)
  34 
  35 #define ZVAL_UTF8_STRING(z, s, flags)          ZVAL_STRING((z), (char*)(s), ((flags) & ZSTR_DUPLICATE))
  36 #define ZVAL_UTF8_STRINGL(z, s, l, flags)      ZVAL_STRINGL((z), (char*)(s), (l), ((flags) & ZSTR_DUPLICATE))
  37 
  38 
  39 /* {{{ void php_clear_warnings() */
  40 void php_clear_warnings(MYSQLI_WARNING *w)
  41 {
  42         MYSQLI_WARNING *n;
  43 
  44         while (w) {
  45                 n = w;
  46                 zval_dtor(&(w->reason));
  47                 zval_dtor(&(w->sqlstate));
  48                 w = w->next;
  49                 efree(n);
  50         }
  51 }
  52 /* }}} */
  53 
  54 
  55 #ifndef MYSQLI_USE_MYSQLND
  56 /* {{{ MYSQLI_WARNING *php_new_warning */
  57 static
  58 MYSQLI_WARNING *php_new_warning(const char *reason, int errorno TSRMLS_DC)
  59 {
  60         MYSQLI_WARNING *w;
  61 
  62         w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING));
  63 
  64         ZVAL_UTF8_STRING(&(w->reason), reason, ZSTR_DUPLICATE);
  65 
  66         ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1,  ZSTR_DUPLICATE);
  67 
  68         w->errorno = errorno;
  69 
  70         return w;
  71 }
  72 /* }}} */
  73 
  74 
  75 /* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */
  76 MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC)
  77 {
  78         MYSQLI_WARNING *w, *first = NULL, *prev = NULL;
  79         MYSQL_RES               *result;
  80         MYSQL_ROW               row;
  81 
  82         if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) {
  83                 return NULL;
  84         }
  85 
  86         result = mysql_store_result(mysql);
  87 
  88         while ((row = mysql_fetch_row(result))) {
  89                 w = php_new_warning(row[2], atoi(row[1]) TSRMLS_CC);
  90                 if (!first) {
  91                         first = w;
  92                 }
  93                 if (prev) {
  94                         prev->next = w;
  95                 }
  96                 prev = w;
  97         }
  98         mysql_free_result(result);
  99         return first;
 100 }
 101 /* }}} */
 102 #else
 103 /* {{{ MYSQLI_WARNING *php_new_warning */
 104 static
 105 MYSQLI_WARNING *php_new_warning(const zval * reason, int errorno TSRMLS_DC)
 106 {
 107         MYSQLI_WARNING *w;
 108 
 109         w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING));
 110 
 111         w->reason = *reason;
 112         zval_copy_ctor(&(w->reason));
 113 
 114         ZVAL_UTF8_STRINGL(&(w->reason),  Z_STRVAL(w->reason), Z_STRLEN(w->reason),  ZSTR_AUTOFREE);
 115 
 116         ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1,  ZSTR_DUPLICATE);
 117 
 118         w->errorno = errorno;
 119 
 120         return w;
 121 }
 122 /* }}} */
 123 
 124 
 125 /* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */
 126 MYSQLI_WARNING * php_get_warnings(MYSQLND_CONN_DATA * mysql TSRMLS_DC)
 127 {
 128         MYSQLI_WARNING  *w, *first = NULL, *prev = NULL;
 129         MYSQL_RES               *result;
 130         zval                    *row;
 131 
 132         if (mysql->m->query(mysql, "SHOW WARNINGS", 13 TSRMLS_CC)) {
 133                 return NULL;
 134         }
 135 
 136         result = mysql->m->use_result(mysql, 0 TSRMLS_CC);
 137 
 138         for (;;) {
 139                 zval **entry;
 140                 int errno;
 141 
 142                 MAKE_STD_ZVAL(row);
 143                 mysqlnd_fetch_into(result, MYSQLND_FETCH_NUM, row, MYSQLND_MYSQLI);
 144                 if (Z_TYPE_P(row) != IS_ARRAY) {
 145                         zval_ptr_dtor(&row);
 146                         break;
 147                 }
 148                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(row));
 149                 /* 0. we don't care about the first */
 150                 zend_hash_move_forward(Z_ARRVAL_P(row));
 151 
 152                 /* 1. Here comes the error no */
 153                 zend_hash_get_current_data(Z_ARRVAL_P(row), (void **)&entry);
 154                 convert_to_long_ex(entry);
 155                 errno = Z_LVAL_PP(entry);
 156                 zend_hash_move_forward(Z_ARRVAL_P(row));
 157 
 158                 /* 2. Here comes the reason */
 159                 zend_hash_get_current_data(Z_ARRVAL_P(row), (void **)&entry);
 160 
 161                 w = php_new_warning(*entry, errno TSRMLS_CC);
 162                 /*
 163                   Don't destroy entry, because the row destroy will decrease
 164                   the refcounter. Decreased twice then mysqlnd_free_result()
 165                   will crash, because it will try to access already freed memory.
 166                 */
 167                 if (!first) {
 168                         first = w;
 169                 }
 170                 if (prev) {
 171                         prev->next = (void *)w;
 172                 }
 173                 prev = w;
 174 
 175                 zval_ptr_dtor(&row);
 176         }
 177 
 178         mysql_free_result(result);
 179         return first;
 180 }
 181 /* }}} */
 182 #endif
 183 
 184 
 185 /* {{{ bool mysqli_warning::next() */
 186 PHP_METHOD(mysqli_warning, next)
 187 {
 188         MYSQLI_WARNING  *w;
 189         zval                    *mysqli_warning;
 190         mysqli_object *obj = (mysqli_object *)zend_objects_get_address(getThis() TSRMLS_CC);
 191 
 192         if (obj->ptr) {
 193                 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
 194                                                                                  &mysqli_warning, mysqli_warning_class_entry) == FAILURE) {
 195                         return;
 196                 }
 197 
 198                 MYSQLI_FETCH_RESOURCE(w, MYSQLI_WARNING *, &mysqli_warning, "mysqli_warning", MYSQLI_STATUS_VALID);
 199 
 200                 if (w && w->next) {
 201                         w = w->next;
 202                 ((MYSQLI_RESOURCE *)(obj->ptr))->ptr = w;
 203                         RETURN_TRUE;
 204                 }
 205         }
 206         RETURN_FALSE;
 207 }
 208 /* }}} */
 209 
 210 
 211 /* {{{ property mysqli_warning_message */
 212 static
 213 int mysqli_warning_message(mysqli_object *obj, zval **retval TSRMLS_DC)
 214 {
 215         MYSQLI_WARNING *w;
 216 
 217         if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) {
 218                 return FAILURE;
 219         }
 220 
 221         w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
 222         MAKE_STD_ZVAL(*retval);
 223         **retval = w->reason;
 224         zval_copy_ctor(*retval);
 225         return SUCCESS;
 226 }
 227 /* }}} */
 228 
 229 
 230 /* {{{ property mysqli_warning_sqlstate */
 231 static
 232 int mysqli_warning_sqlstate(mysqli_object *obj, zval **retval TSRMLS_DC)
 233 {
 234         MYSQLI_WARNING *w;
 235 
 236         if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) {
 237                 return FAILURE;
 238         }
 239 
 240         w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
 241         MAKE_STD_ZVAL(*retval);
 242         **retval = w->sqlstate;
 243         zval_copy_ctor(*retval);
 244         return SUCCESS;
 245 }
 246 /* }}} */
 247 
 248 
 249 /* {{{ property mysqli_warning_error */
 250 static
 251 int mysqli_warning_errno(mysqli_object *obj, zval **retval TSRMLS_DC)
 252 {
 253         MYSQLI_WARNING *w;
 254 
 255         if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) {
 256                 return FAILURE;
 257         }
 258         w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
 259         MAKE_STD_ZVAL(*retval);
 260         ZVAL_LONG(*retval, w->errorno);
 261         return SUCCESS;
 262 }
 263 /* }}} */
 264 
 265 /* {{{ mysqli_warning_construct(object obj) */
 266 PHP_METHOD(mysqli_warning, __construct)
 267 {
 268         zval                    *z;
 269         mysqli_object   *obj;
 270 #ifndef MYSQLI_USE_MYSQLND
 271         MYSQL                   *hdl;
 272 #endif
 273         MYSQLI_WARNING  *w;
 274         MYSQLI_RESOURCE *mysqli_resource;
 275 
 276         if (ZEND_NUM_ARGS() != 1) {
 277                 WRONG_PARAM_COUNT;
 278         }
 279         if (zend_parse_parameters(1 TSRMLS_CC, "o", &z)==FAILURE) {
 280                 return;
 281         }
 282         obj = (mysqli_object *)zend_object_store_get_object(z TSRMLS_CC);\
 283 
 284         if (obj->zo.ce == mysqli_link_class_entry) {
 285                 MY_MYSQL *mysql;
 286                 MYSQLI_FETCH_RESOURCE_CONN(mysql, &z, MYSQLI_STATUS_VALID);
 287                 if (mysql_warning_count(mysql->mysql)) {
 288 #ifndef MYSQLI_USE_MYSQLND
 289                         w = php_get_warnings(mysql->mysql TSRMLS_CC);
 290 #else
 291                         w = php_get_warnings(mysql->mysql->data TSRMLS_CC);
 292 #endif
 293                 } else {
 294                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found");
 295                         RETURN_FALSE;
 296                 }
 297         } else if (obj->zo.ce == mysqli_stmt_class_entry) {
 298                 MY_STMT *stmt;
 299                 MYSQLI_FETCH_RESOURCE_STMT(stmt, &z, MYSQLI_STATUS_VALID);
 300 #ifndef MYSQLI_USE_MYSQLND
 301                 hdl = mysqli_stmt_get_connection(stmt->stmt);
 302                 if (mysql_warning_count(hdl)) {
 303                         w = php_get_warnings(hdl TSRMLS_CC);
 304 #else
 305                 if (mysqlnd_stmt_warning_count(stmt->stmt)) {
 306                         w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC);
 307 #endif
 308                 } else {
 309                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found");
 310                         RETURN_FALSE;
 311                 }
 312         } else {
 313                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid class argument");
 314                 RETURN_FALSE;
 315         }
 316 
 317         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
 318         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
 319         mysqli_resource->status = MYSQLI_STATUS_VALID;
 320 
 321         if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_warning_class_entry TSRMLS_CC)) {
 322                 MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
 323         } else {
 324                 ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
 325         }
 326 
 327 }
 328 /* }}} */
 329 
 330 /* {{{ mysqli_warning_methods */
 331 const zend_function_entry mysqli_warning_methods[] = {
 332         PHP_ME(mysqli_warning, __construct,             NULL, ZEND_ACC_PROTECTED)
 333         PHP_ME(mysqli_warning, next,                    NULL, ZEND_ACC_PUBLIC)
 334         {NULL, NULL, NULL}
 335 };
 336 /* }}} */
 337 
 338 /* {{{ mysqli_warning_property_entries */
 339 const mysqli_property_entry mysqli_warning_property_entries[] = {
 340         {"message", sizeof("message") - 1, mysqli_warning_message, NULL},
 341         {"sqlstate", sizeof("sqlstate") - 1, mysqli_warning_sqlstate, NULL},
 342         {"errno", sizeof("errno") - 1, mysqli_warning_errno, NULL},
 343         {NULL, 0, NULL, NULL}
 344 };
 345 /* }}} */
 346 
 347 /* {{{ mysqli_warning_property_info_entries */
 348 const zend_property_info mysqli_warning_property_info_entries[] = {
 349         {ZEND_ACC_PUBLIC, "message",    sizeof("message") - 1,  -1, 0, NULL, 0, NULL},
 350         {ZEND_ACC_PUBLIC, "sqlstate",   sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL},
 351         {ZEND_ACC_PUBLIC, "errno",              sizeof("errno") - 1,    -1, 0, NULL, 0, NULL},
 352         {0,                                     NULL,                   0,                                      -1, 0, NULL, 0, NULL}
 353 };
 354 /* }}} */
 355 
 356 
 357 /*
 358  * Local variables:
 359  * tab-width: 4
 360  * c-basic-offset: 4
 361  * indent-tabs-mode: t
 362  * End:
 363  * vim600: noet sw=4 ts=4 fdm=marker
 364  * vim<600: noet sw=4 ts=4
 365  */

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