Annotation of embedaddon/php/ext/mysqli/mysqli_warning.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
                      5:   | Copyright (c) 1997-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:   | 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
1.1.1.2 ! misho     105: MYSQLI_WARNING *php_new_warning(const zval * reason, int errorno TSRMLS_DC)
1.1       misho     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) */
1.1.1.2 ! misho     126: MYSQLI_WARNING * php_get_warnings(MYSQLND_CONN_DATA * mysql TSRMLS_DC)
1.1       misho     127: {
                    128:        MYSQLI_WARNING  *w, *first = NULL, *prev = NULL;
                    129:        MYSQL_RES               *result;
                    130:        zval                    *row;
                    131: 
1.1.1.2 ! misho     132:        if (mysql->m->query(mysql, "SHOW WARNINGS", 13 TSRMLS_CC)) {
1.1       misho     133:                return NULL;
                    134:        }
                    135: 
1.1.1.2 ! misho     136:        result = mysql->m->use_result(mysql TSRMLS_CC);
1.1       misho     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;
1.1.1.2 ! misho     270: #ifndef MYSQLI_USE_MYSQLND
1.1       misho     271:        MYSQL                   *hdl;
1.1.1.2 ! misho     272: #endif
1.1       misho     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);
1.1.1.2 ! misho     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:                }
1.1       misho     297:        } else if (obj->zo.ce == mysqli_stmt_class_entry) {
                    298:                MY_STMT *stmt;
                    299:                MYSQLI_FETCH_RESOURCE_STMT(stmt, &z, MYSQLI_STATUS_VALID);
1.1.1.2 ! misho     300: #ifndef MYSQLI_USE_MYSQLND
1.1       misho     301:                hdl = mysqli_stmt_get_connection(stmt->stmt);
1.1.1.2 ! misho     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:                }
1.1       misho     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 */
1.1.1.2 ! misho     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}
1.1       misho     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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>